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"
59#include <ostream> // for std::ostream
60
61namespace Sacado {
62 namespace ELRCacheFad {
63
64 //
65 // UnaryPlusOp
66 //
67
68 template <typename ExprT>
69 class UnaryPlusOp {};
70
71 template <typename ExprT>
72 class Expr< UnaryPlusOp<ExprT> > {
73 public:
74
75 typedef typename ExprT::value_type value_type;
76 typedef typename ExprT::scalar_type scalar_type;
77
78 typedef typename ExprT::base_expr_type base_expr_type;
79
80 static const int num_args = ExprT::num_args;
81
82 static const bool is_linear = true;
83
85 explicit Expr(const ExprT& expr_) : expr(expr_) {}
86
88 int size() const { return expr.size(); }
89
90 template <int Arg>
92 bool isActive() const { return expr.template isActive<Arg>(); }
93
95 bool updateValue() const { return expr.updateValue(); }
96
98 void cache() const {
99 expr.cache();
100 }
101
103 value_type val() const {
104 return expr.val();
105 }
106
109 value_type partials[]) const {
110 expr.computePartials(bar, partials);
111 }
112
114 void getTangents(int i, value_type dots[]) const {
115 expr.getTangents(i, dots); }
116
117 template <int Arg>
119 return expr.template getTangent<Arg>(i);
120 }
121
123 bool isLinear() const {
124 return expr.isLinear();
125 }
126
128 bool hasFastAccess() const {
129 return expr.hasFastAccess();
130 }
131
133 const value_type dx(int i) const {
134 return expr.dx(i);
135 }
136
138 const value_type fastAccessDx(int i) const {
139 return expr.fastAccessDx(i);
140 }
141
143 const value_type* getDx(int j) const {
144 return expr.getDx(j);
145 }
146
147 protected:
148
149 const ExprT& expr;
150 };
151
152 template <typename T>
155 operator+ (const Expr<T>& expr)
156 {
157 typedef UnaryPlusOp< Expr<T> > expr_t;
158
159 return Expr<expr_t>(expr);
160 }
161
162 //
163 // UnaryMinusOp
164 //
165 template <typename ExprT>
166 class UnaryMinusOp {};
167
168 template <typename ExprT>
169 class Expr< UnaryMinusOp<ExprT> > {
170 public:
171
172 typedef typename ExprT::value_type value_type;
173 typedef typename ExprT::scalar_type scalar_type;
174
175 typedef typename ExprT::base_expr_type base_expr_type;
176
177 static const int num_args = ExprT::num_args;
178
179 static const bool is_linear = true;
180
182 explicit Expr(const ExprT& expr_) : expr(expr_) {}
183
185 int size() const { return expr.size(); }
186
187 template <int Arg>
189 bool isActive() const { return expr.template isActive<Arg>(); }
190
192 bool updateValue() const { return expr.updateValue(); }
193
195 void cache() const {
196 expr.cache();
197 }
198
200 value_type val() const {
201 return -expr.val();
202 }
203
206 value_type partials[]) const {
207 expr.computePartials(-bar, partials);
208 }
209
211 void getTangents(int i, value_type dots[]) const {
212 expr.getTangents(i, dots); }
213
214 template <int Arg>
217 return expr.template getTangent<Arg>(i);
218 }
219
221 bool isLinear() const {
222 return expr.isLinear();
223 }
224
226 bool hasFastAccess() const {
227 return expr.hasFastAccess();
228 }
229
231 const value_type dx(int i) const {
232 return -expr.dx(i);
233 }
234
236 const value_type fastAccessDx(int i) const {
237 return -expr.fastAccessDx(i);
238 }
239
241 const value_type* getDx(int j) const {
242 return expr.getDx(j);
243 }
244
245 protected:
246
247 const ExprT& expr;
248 };
249
250 template <typename T>
253 operator- (const Expr<T>& expr)
254 {
255 typedef UnaryMinusOp< Expr<T> > expr_t;
256
257 return Expr<expr_t>(expr);
258 }
259
260 //
261 // AbsOp
262 //
263
264 template <typename ExprT>
265 class AbsOp {};
266
267 template <typename ExprT>
268 class Expr< AbsOp<ExprT> > {
269 public:
270
271 typedef typename ExprT::value_type value_type;
272 typedef typename ExprT::scalar_type scalar_type;
273
274 typedef typename ExprT::base_expr_type base_expr_type;
275
276 static const int num_args = ExprT::num_args;
277
278 static const bool is_linear = false;
279
281 explicit Expr(const ExprT& expr_) : expr(expr_) {}
282
284 int size() const { return expr.size(); }
285
286 template <int Arg>
288 bool isActive() const { return expr.template isActive<Arg>(); }
289
291 bool updateValue() const { return expr.updateValue(); }
292
294 void cache() const {
295 expr.cache();
296 v = expr.val();
297 v_pos = (v >= 0);
298 }
299
301 value_type val() const {
302 return std::abs(v);
303 }
304
307 value_type partials[]) const {
308 if (v_pos)
309 expr.computePartials(bar, partials);
310 else
311 expr.computePartials(-bar, partials);
312 }
313
315 void getTangents(int i, value_type dots[]) const {
316 expr.getTangents(i, dots); }
317
318 template <int Arg>
321 return expr.template getTangent<Arg>(i);
322 }
323
325 bool isLinear() const {
326 return false;
327 }
328
330 bool hasFastAccess() const {
331 return expr.hasFastAccess();
332 }
333
335 const value_type dx(int i) const {
336 if (v_pos) return expr.dx(i);
337 else return -expr.dx(i);
338 }
339
341 const value_type fastAccessDx(int i) const {
342 if (v_pos) return expr.fastAccessDx(i);
343 else return -expr.fastAccessDx(i);
344 }
345
347 const value_type* getDx(int j) const {
348 return expr.getDx(j);
349 }
350
351 protected:
352
353 const ExprT& expr;
354 mutable value_type v;
355 mutable bool v_pos;
356 };
357
358 template <typename T>
361 abs (const Expr<T>& expr)
362 {
363 typedef AbsOp< Expr<T> > expr_t;
364
365 return Expr<expr_t>(expr);
366 }
367
368 //
369 // FAbsOp
370 //
371
372 template <typename ExprT>
373 class FAbsOp {};
374
375 template <typename ExprT>
376 class Expr< FAbsOp<ExprT> > {
377 public:
378
379 typedef typename ExprT::value_type value_type;
380 typedef typename ExprT::scalar_type scalar_type;
381
382 typedef typename ExprT::base_expr_type base_expr_type;
383
384 static const int num_args = ExprT::num_args;
385
386 static const bool is_linear = false;
387
389 explicit Expr(const ExprT& expr_) : expr(expr_) {}
390
392 int size() const { return expr.size(); }
393
394 template <int Arg>
396 bool isActive() const { return expr.template isActive<Arg>(); }
397
399 bool updateValue() const { return expr.updateValue(); }
400
402 void cache() const {
403 expr.cache();
404 v = expr.val();
405 v_pos = (v >= 0);
406 }
407
409 value_type val() const {
410 return std::fabs(v);
411 }
412
415 value_type partials[]) const {
416 if (v_pos)
417 expr.computePartials(bar, partials);
418 else
419 expr.computePartials(-bar, partials);
420 }
421
423 void getTangents(int i, value_type dots[]) const {
424 expr.getTangents(i, dots); }
425
426 template <int Arg>
429 return expr.template getTangent<Arg>(i);
430 }
431
433 bool isLinear() const {
434 return false;
435 }
436
438 bool hasFastAccess() const {
439 return expr.hasFastAccess();
440 }
441
443 const value_type dx(int i) const {
444 if (v_pos) return expr.dx(i);
445 else return -expr.dx(i);
446 }
447
449 const value_type fastAccessDx(int i) const {
450 if (v_pos) return expr.fastAccessDx(i);
451 else return -expr.fastAccessDx(i);
452 }
453
455 const value_type* getDx(int j) const {
456 return expr.getDx(j);
457 }
458
459 protected:
460
461 const ExprT& expr;
462 mutable value_type v;
463 mutable bool v_pos;
464 };
465
466 template <typename T>
469 fabs (const Expr<T>& expr)
470 {
471 typedef FAbsOp< Expr<T> > expr_t;
472
473 return Expr<expr_t>(expr);
474 }
475
476 }
477}
478
479#define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE) \
480namespace Sacado { \
481 namespace ELRCacheFad { \
482 \
483 template <typename ExprT> \
484 class OP {}; \
485 \
486 template <typename ExprT> \
487 class Expr< OP<ExprT> > { \
488 public: \
489 \
490 typedef typename ExprT::value_type value_type; \
491 typedef typename ExprT::scalar_type scalar_type; \
492 \
493 typedef typename ExprT::base_expr_type base_expr_type; \
494 \
495 static const int num_args = ExprT::num_args; \
496 \
497 static const bool is_linear = false; \
498 \
499 SACADO_INLINE_FUNCTION \
500 explicit Expr(const ExprT& expr_) : expr(expr_) {} \
501 \
502 SACADO_INLINE_FUNCTION \
503 int size() const { return expr.size(); } \
504 \
505 template <int Arg> \
506 SACADO_INLINE_FUNCTION \
507 bool isActive() const { return expr.template isActive<Arg>(); } \
508 \
509 SACADO_INLINE_FUNCTION \
510 bool updateValue() const { return expr.updateValue(); } \
511 \
512 SACADO_INLINE_FUNCTION \
513 void cache() const { \
514 expr.cache(); \
515 v = expr.val(); \
516 PARTIAL; \
517 } \
518 \
519 SACADO_INLINE_FUNCTION \
520 value_type val() const { \
521 return VALUE; \
522 } \
523 \
524 SACADO_INLINE_FUNCTION \
525 void computePartials(const value_type& bar, \
526 value_type partials[]) const { \
527 expr.computePartials(bar*a, partials); \
528 } \
529 \
530 SACADO_INLINE_FUNCTION \
531 void getTangents(int i, value_type dots[]) const { \
532 expr.getTangents(i, dots); } \
533 \
534 template <int Arg> \
535 SACADO_INLINE_FUNCTION \
536 value_type getTangent(int i) const { \
537 return expr.template getTangent<Arg>(i); \
538 } \
539 \
540 SACADO_INLINE_FUNCTION \
541 bool isLinear() const { \
542 return false; \
543 } \
544 \
545 SACADO_INLINE_FUNCTION \
546 bool hasFastAccess() const { \
547 return expr.hasFastAccess(); \
548 } \
549 \
550 SACADO_INLINE_FUNCTION \
551 const value_type dx(int i) const { \
552 return expr.dx(i)*a; \
553 } \
554 \
555 SACADO_INLINE_FUNCTION \
556 const value_type fastAccessDx(int i) const { \
557 return expr.fastAccessDx(i)*a; \
558 } \
559 \
560 SACADO_INLINE_FUNCTION \
561 const value_type* getDx(int j) const { \
562 return expr.getDx(j); \
563 } \
564 \
565 protected: \
566 \
567 const ExprT& expr; \
568 mutable value_type v; \
569 mutable value_type a; \
570 }; \
571 \
572 template <typename T> \
573 SACADO_INLINE_FUNCTION \
574 Expr< OP< Expr<T> > > \
575 OPNAME (const Expr<T>& expr) \
576 { \
577 typedef OP< Expr<T> > expr_t; \
578 \
579 return Expr<expr_t>(expr); \
580 } \
581 } \
582}
583
585 ExpOp,
586 a = std::exp(v),
587 a)
590 a=scalar_type(1.0)/v,
591 std::log(v))
594 a = scalar_type(1.0)/(std::log(scalar_type(10.0))*v),
595 std::log10(v))
598 a = scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)),
599 std::sqrt(v))
600FAD_UNARYOP_MACRO(safe_sqrt,
602 a = (v == value_type(0.0) ? value_type(0.0) : value_type(scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)))),
603 std::sqrt(v))
606 a = -std::sin(v),
607 std::cos(v))
610 a = std::cos(v),
611 std::sin(v))
614 a = scalar_type(1.0)+std::tan(v)*std::tan(v),
615 std::tan(v))
618 a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
619 std::acos(v))
622 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
623 std::asin(v))
626 a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
627 std::atan(v))
630 a = std::sinh(v),
631 std::cosh(v))
634 a = std::cosh(v),
635 std::sinh(v))
638 a = scalar_type(1.0)-std::tanh(v)*std::tanh(v),
639 std::tanh(v))
642 a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
643 std::acosh(v))
646 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
647 std::asinh(v))
650 a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
651 std::atanh(v))
652#ifdef HAVE_SACADO_CXX11
654 CbrtOp,
655 a = scalar_type(1.0)/(scalar_type(3.0)*std::cbrt(v*v)),
656 std::cbrt(v))
657#endif
658
659#undef FAD_UNARYOP_MACRO
660
661//
662// Binary operators
663//
664namespace Sacado {
665 namespace ELRCacheFad {
666
667 //
668 // AdditionOp
669 //
670
671 template <typename ExprT1, typename ExprT2>
672 class AdditionOp {};
673
674 template <typename ExprT1, typename ExprT2>
675 class Expr< AdditionOp<ExprT1,ExprT2> > {
676
677 public:
678
679 typedef typename ExprT1::value_type value_type_1;
680 typedef typename ExprT2::value_type value_type_2;
681 typedef typename Sacado::Promote<value_type_1,
682 value_type_2>::type value_type;
683 typedef typename ExprT1::scalar_type scalar_type_1;
684 typedef typename ExprT2::scalar_type scalar_type_2;
685 typedef typename Sacado::Promote<scalar_type_1,
686 scalar_type_2>::type scalar_type;
687
688 typedef typename ExprT1::base_expr_type base_expr_type_1;
689 typedef typename ExprT2::base_expr_type base_expr_type_2;
690 typedef typename Sacado::Promote<base_expr_type_1,
691 base_expr_type_2>::type base_expr_type;
692
693 static const int num_args1 = ExprT1::num_args;
694 static const int num_args2 = ExprT2::num_args;
695 static const int num_args = num_args1 + num_args2;
696
697 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
698
700 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
701 expr1(expr1_), expr2(expr2_) {}
702
704 int size() const {
705 int sz1 = expr1.size(), sz2 = expr2.size();
706 return sz1 > sz2 ? sz1 : sz2;
707 }
708
709 template <int Arg>
711 bool isActive() const {
712 if (Arg < num_args1)
713 return expr1.template isActive<Arg>();
714 else
715 return expr2.template isActive<Arg-num_args1>();
716 }
717
719 bool updateValue() const {
720 return expr1.updateValue() && expr2.updateValue();
721 }
722
724 void cache() const {
725 expr1.cache();
726 expr2.cache();
727 }
728
730 value_type val() const {
731 return expr1.val()+expr2.val();
732 }
733
735 void computePartials(const value_type& bar,
736 value_type partials[]) const {
737 if (num_args1 > 0)
738 expr1.computePartials(bar, partials);
739 if (num_args2 > 0)
740 expr2.computePartials(bar, partials+num_args1);
741 }
742
744 void getTangents(int i, value_type dots[]) const {
745 expr1.getTangents(i, dots);
746 expr2.getTangents(i, dots+num_args1);
747 }
748
749 template <int Arg>
751 value_type getTangent(int i) const {
752 if (Arg < num_args1)
753 return expr1.template getTangent<Arg>(i);
754 else
755 return expr2.template getTangent<Arg-num_args1>(i);
756 }
757
759 bool isLinear() const {
760 return expr1.isLinear() && expr2.isLinear();
761 }
762
764 bool hasFastAccess() const {
765 return expr1.hasFastAccess() && expr2.hasFastAccess();
766 }
767
769 const value_type dx(int i) const {
770 return expr1.dx(i) + expr2.dx(i);
771 }
772
774 const value_type fastAccessDx(int i) const {
775 return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
776 }
777
779 const value_type* getDx(int j) const {
780 if (j < num_args1)
781 return expr1.getDx(j);
782 else
783 return expr2.getDx(j-num_args1);
784 }
785
786 protected:
787
788 const ExprT1& expr1;
789 const ExprT2& expr2;
790
791 };
792
793 template <typename ExprT1, typename T2>
794 class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
795
796 public:
797
798 typedef ConstExpr<T2> ExprT2;
799 typedef typename ExprT1::value_type value_type_1;
800 typedef typename ExprT2::value_type value_type_2;
801 typedef typename Sacado::Promote<value_type_1,
802 value_type_2>::type value_type;
803 typedef typename ExprT1::scalar_type scalar_type_1;
804 typedef typename ExprT2::scalar_type scalar_type_2;
805 typedef typename Sacado::Promote<scalar_type_1,
806 scalar_type_2>::type scalar_type;
807
808 typedef typename ExprT1::base_expr_type base_expr_type_1;
809 typedef typename ExprT2::base_expr_type base_expr_type_2;
810 typedef typename Sacado::Promote<base_expr_type_1,
811 base_expr_type_2>::type base_expr_type;
812
813 static const int num_args = ExprT1::num_args;
814
815 static const bool is_linear = ExprT1::is_linear;
816
818 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
819 expr1(expr1_), expr2(expr2_) {}
820
822 int size() const {
823 return expr1.size();
824 }
825
826 template <int Arg>
828 bool isActive() const {
829 return expr1.template isActive<Arg>();
830 }
831
833 bool updateValue() const {
834 return expr1.updateValue();
835 }
836
838 void cache() const {
839 expr1.cache();
840 }
841
843 value_type val() const {
844 return expr1.val() + expr2.val();
845 }
846
848 void computePartials(const value_type& bar,
849 value_type partials[]) const {
850 expr1.computePartials(bar, partials);
851 }
852
854 void getTangents(int i, value_type dots[]) const {
855 expr1.getTangents(i, dots);
856 }
857
858 template <int Arg>
860 value_type getTangent(int i) const {
861 return expr1.template getTangent<Arg>(i);
862 }
863
865 bool isLinear() const {
866 return expr1.isLinear();
867 }
868
870 bool hasFastAccess() const {
871 return expr1.hasFastAccess();
872 }
873
875 const value_type dx(int i) const {
876 return expr1.dx(i);
877 }
878
880 const value_type fastAccessDx(int i) const {
881 return expr1.fastAccessDx(i);
882 }
883
885 const value_type* getDx(int j) const {
886 return expr1.getDx(j);
887 }
888
889 protected:
890
891 const ExprT1& expr1;
892 ExprT2 expr2;
893
894 };
895
896 template <typename T1, typename ExprT2>
897 class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
898
899 public:
900
901 typedef ConstExpr<T1> ExprT1;
902 typedef typename ExprT1::value_type value_type_1;
903 typedef typename ExprT2::value_type value_type_2;
904 typedef typename Sacado::Promote<value_type_1,
905 value_type_2>::type value_type;
906 typedef typename ExprT1::scalar_type scalar_type_1;
907 typedef typename ExprT2::scalar_type scalar_type_2;
908 typedef typename Sacado::Promote<scalar_type_1,
909 scalar_type_2>::type scalar_type;
910
911 typedef typename ExprT1::base_expr_type base_expr_type_1;
912 typedef typename ExprT2::base_expr_type base_expr_type_2;
913 typedef typename Sacado::Promote<base_expr_type_1,
914 base_expr_type_2>::type base_expr_type;
915
916 static const int num_args = ExprT2::num_args;
917
918 static const bool is_linear = ExprT2::is_linear;
919
921 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
922 expr1(expr1_), expr2(expr2_) {}
923
925 int size() const {
926 return expr2.size();
927 }
928
929 template <int Arg>
931 bool isActive() const {
932 return expr2.template isActive<Arg>();
933 }
934
936 bool updateValue() const {
937 return expr2.updateValue();
938 }
939
941 void cache() const {
942 expr2.cache();
943 }
944
946 value_type val() const {
947 return expr1.val() + expr2.val();
948 }
949
951 void computePartials(const value_type& bar,
952 value_type partials[]) const {
953 expr2.computePartials(bar, partials);
954 }
955
957 void getTangents(int i, value_type dots[]) const {
958 expr2.getTangents(i, dots);
959 }
960
961 template <int Arg>
963 value_type getTangent(int i) const {
964 return expr2.template getTangent<Arg>(i);
965 }
966
968 bool isLinear() const {
969 return expr2.isLinear();
970 }
971
973 bool hasFastAccess() const {
974 return expr2.hasFastAccess();
975 }
976
978 const value_type dx(int i) const {
979 return expr2.dx(i);
980 }
981
983 const value_type fastAccessDx(int i) const {
984 return expr2.fastAccessDx(i);
985 }
986
988 const value_type* getDx(int j) const {
989 return expr2.getDx(j);
990 }
991
992 protected:
993
994 ExprT1 expr1;
995 const ExprT2& expr2;
996
997 };
998
999 //
1000 // SubtractionOp
1001 //
1002
1003 template <typename ExprT1, typename ExprT2>
1004 class SubtractionOp {};
1005
1006 template <typename ExprT1, typename ExprT2>
1007 class Expr< SubtractionOp<ExprT1,ExprT2> > {
1008
1009 public:
1010
1011 typedef typename ExprT1::value_type value_type_1;
1012 typedef typename ExprT2::value_type value_type_2;
1013 typedef typename Sacado::Promote<value_type_1,
1014 value_type_2>::type value_type;
1015 typedef typename ExprT1::scalar_type scalar_type_1;
1016 typedef typename ExprT2::scalar_type scalar_type_2;
1017 typedef typename Sacado::Promote<scalar_type_1,
1018 scalar_type_2>::type scalar_type;
1019
1020 typedef typename ExprT1::base_expr_type base_expr_type_1;
1021 typedef typename ExprT2::base_expr_type base_expr_type_2;
1022 typedef typename Sacado::Promote<base_expr_type_1,
1023 base_expr_type_2>::type base_expr_type;
1024
1025 static const int num_args1 = ExprT1::num_args;
1026 static const int num_args2 = ExprT2::num_args;
1027 static const int num_args = num_args1 + num_args2;
1028
1029 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
1030
1032 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1033 expr1(expr1_), expr2(expr2_) {}
1034
1036 int size() const {
1037 int sz1 = expr1.size(), sz2 = expr2.size();
1038 return sz1 > sz2 ? sz1 : sz2;
1039 }
1040
1041 template <int Arg>
1043 bool isActive() const {
1044 if (Arg < num_args1)
1045 return expr1.template isActive<Arg>();
1046 else
1047 return expr2.template isActive<Arg-num_args1>();
1048 }
1049
1051 bool updateValue() const {
1052 return expr1.updateValue() && expr2.updateValue();
1053 }
1054
1056 void cache() const {
1057 expr1.cache();
1058 expr2.cache();
1059 }
1060
1062 value_type val() const {
1063 return expr1.val()-expr2.val();
1064 }
1065
1067 void computePartials(const value_type& bar,
1068 value_type partials[]) const {
1069 if (num_args1 > 0)
1070 expr1.computePartials(bar, partials);
1071 if (num_args2 > 0)
1072 expr2.computePartials(-bar, partials+num_args1);
1073 }
1074
1076 void getTangents(int i, value_type dots[]) const {
1077 expr1.getTangents(i, dots);
1078 expr2.getTangents(i, dots+num_args1);
1079 }
1080
1081 template <int Arg>
1083 value_type getTangent(int i) const {
1084 if (Arg < num_args1)
1085 return expr1.template getTangent<Arg>(i);
1086 else
1087 return expr2.template getTangent<Arg-num_args1>(i);
1088 }
1089
1091 bool isLinear() const {
1092 return expr1.isLinear() && expr2.isLinear();
1093 }
1094
1096 bool hasFastAccess() const {
1097 return expr1.hasFastAccess() && expr2.hasFastAccess();
1098 }
1099
1101 const value_type dx(int i) const {
1102 return expr1.dx(i) - expr2.dx(i);
1103 }
1104
1106 const value_type fastAccessDx(int i) const {
1107 return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
1108 }
1109
1111 const value_type* getDx(int j) const {
1112 if (j < num_args1)
1113 return expr1.getDx(j);
1114 else
1115 return expr2.getDx(j-num_args1);
1116 }
1117
1118 protected:
1119
1120 const ExprT1& expr1;
1121 const ExprT2& expr2;
1122
1123 };
1124
1125 template <typename ExprT1, typename T2>
1126 class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
1127
1128 public:
1129
1130 typedef ConstExpr<T2> ExprT2;
1131 typedef typename ExprT1::value_type value_type_1;
1132 typedef typename ExprT2::value_type value_type_2;
1133 typedef typename Sacado::Promote<value_type_1,
1134 value_type_2>::type value_type;
1135 typedef typename ExprT1::scalar_type scalar_type_1;
1136 typedef typename ExprT2::scalar_type scalar_type_2;
1137 typedef typename Sacado::Promote<scalar_type_1,
1138 scalar_type_2>::type scalar_type;
1139
1140 typedef typename ExprT1::base_expr_type base_expr_type_1;
1141 typedef typename ExprT2::base_expr_type base_expr_type_2;
1142 typedef typename Sacado::Promote<base_expr_type_1,
1143 base_expr_type_2>::type base_expr_type;
1144
1145 static const int num_args = ExprT1::num_args;
1146
1147 static const bool is_linear = ExprT1::is_linear;
1148
1150 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1151 expr1(expr1_), expr2(expr2_) {}
1152
1154 int size() const {
1155 return expr1.size();
1156 }
1157
1158 template <int Arg>
1160 bool isActive() const {
1161 return expr1.template isActive<Arg>();
1162 }
1163
1165 bool updateValue() const {
1166 return expr1.updateValue();
1167 }
1168
1170 void cache() const {
1171 expr1.cache();
1172 }
1173
1175 value_type val() const {
1176 return expr1.val() - expr2.val();
1177 }
1178
1180 void computePartials(const value_type& bar,
1181 value_type partials[]) const {
1182 expr1.computePartials(bar, partials);
1183 }
1184
1186 void getTangents(int i, value_type dots[]) const {
1187 expr1.getTangents(i, dots);
1188 }
1189
1190 template <int Arg>
1192 value_type getTangent(int i) const {
1193 return expr1.template getTangent<Arg>(i);
1194 }
1195
1197 bool isLinear() const {
1198 return expr1.isLinear();
1199 }
1200
1202 bool hasFastAccess() const {
1203 return expr1.hasFastAccess();
1204 }
1205
1207 const value_type dx(int i) const {
1208 return expr1.dx(i);
1209 }
1210
1212 const value_type fastAccessDx(int i) const {
1213 return expr1.fastAccessDx(i);
1214 }
1215
1217 const value_type* getDx(int j) const {
1218 return expr1.getDx(j);
1219 }
1220
1221 protected:
1222
1223 const ExprT1& expr1;
1224 ExprT2 expr2;
1225
1226 };
1227
1228 template <typename T1, typename ExprT2>
1229 class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
1230
1231 public:
1232
1233 typedef ConstExpr<T1> ExprT1;
1234 typedef typename ExprT1::value_type value_type_1;
1235 typedef typename ExprT2::value_type value_type_2;
1236 typedef typename Sacado::Promote<value_type_1,
1237 value_type_2>::type value_type;
1238 typedef typename ExprT1::scalar_type scalar_type_1;
1239 typedef typename ExprT2::scalar_type scalar_type_2;
1240 typedef typename Sacado::Promote<scalar_type_1,
1241 scalar_type_2>::type scalar_type;
1242
1243 typedef typename ExprT1::base_expr_type base_expr_type_1;
1244 typedef typename ExprT2::base_expr_type base_expr_type_2;
1245 typedef typename Sacado::Promote<base_expr_type_1,
1246 base_expr_type_2>::type base_expr_type;
1247
1248 static const int num_args = ExprT2::num_args;
1249
1250 static const bool is_linear = ExprT2::is_linear;
1251
1253 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1254 expr1(expr1_), expr2(expr2_) {}
1255
1257 int size() const {
1258 return expr2.size();
1259 }
1260
1261 template <int Arg>
1263 bool isActive() const {
1264 return expr2.template isActive<Arg>();
1265 }
1266
1268 bool updateValue() const {
1269 return expr2.updateValue();
1270 }
1271
1273 void cache() const {
1274 expr2.cache();
1275 }
1276
1278 value_type val() const {
1279 return expr1.val() - expr2.val();
1280 }
1281
1283 void computePartials(const value_type& bar,
1284 value_type partials[]) const {
1285 expr2.computePartials(-bar, partials);
1286 }
1287
1289 void getTangents(int i, value_type dots[]) const {
1290 expr2.getTangents(i, dots);
1291 }
1292
1293 template <int Arg>
1295 value_type getTangent(int i) const {
1296 return expr2.template getTangent<Arg>(i);
1297 }
1298
1300 bool isLinear() const {
1301 return expr2.isLinear();
1302 }
1303
1305 bool hasFastAccess() const {
1306 return expr2.hasFastAccess();
1307 }
1308
1310 const value_type dx(int i) const {
1311 return -expr2.dx(i);
1312 }
1313
1315 const value_type fastAccessDx(int i) const {
1316 return -expr2.fastAccessDx(i);
1317 }
1318
1320 const value_type* getDx(int j) const {
1321 return expr2.getDx(j);
1322 }
1323
1324 protected:
1325
1326 ExprT1 expr1;
1327 const ExprT2& expr2;
1328
1329 };
1330
1331 //
1332 // MultiplicationOp
1333 //
1334
1335 template <typename ExprT1, typename ExprT2>
1336 class MultiplicationOp {};
1337
1338 template <typename ExprT1, typename ExprT2>
1339 class Expr< MultiplicationOp<ExprT1,ExprT2> > {
1340
1341 public:
1342
1343 typedef typename ExprT1::value_type value_type_1;
1344 typedef typename ExprT2::value_type value_type_2;
1345 typedef typename Sacado::Promote<value_type_1,
1346 value_type_2>::type value_type;
1347 typedef typename ExprT1::scalar_type scalar_type_1;
1348 typedef typename ExprT2::scalar_type scalar_type_2;
1349 typedef typename Sacado::Promote<scalar_type_1,
1350 scalar_type_2>::type scalar_type;
1351
1352 typedef typename ExprT1::base_expr_type base_expr_type_1;
1353 typedef typename ExprT2::base_expr_type base_expr_type_2;
1354 typedef typename Sacado::Promote<base_expr_type_1,
1355 base_expr_type_2>::type base_expr_type;
1356
1357 static const int num_args1 = ExprT1::num_args;
1358 static const int num_args2 = ExprT2::num_args;
1359 static const int num_args = num_args1 + num_args2;
1360
1361 static const bool is_linear = false;
1362
1364 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1365 expr1(expr1_), expr2(expr2_) {}
1366
1368 int size() const {
1369 int sz1 = expr1.size(), sz2 = expr2.size();
1370 return sz1 > sz2 ? sz1 : sz2;
1371 }
1372
1373 template <int Arg>
1375 bool isActive() const {
1376 if (Arg < num_args1)
1377 return expr1.template isActive<Arg>();
1378 else
1379 return expr2.template isActive<Arg-num_args1>();
1380 }
1381
1383 bool updateValue() const {
1384 return expr1.updateValue() && expr2.updateValue();
1385 }
1386
1388 void cache() const {
1389 expr1.cache();
1390 expr2.cache();
1391 v1 = expr1.val();
1392 v2 = expr2.val();
1393 }
1394
1396 value_type val() const {
1397 return v1*v2;
1398 }
1399
1401 void computePartials(const value_type& bar,
1402 value_type partials[]) const {
1403 if (num_args1 > 0)
1404 expr1.computePartials(bar*v2, partials);
1405 if (num_args2 > 0)
1406 expr2.computePartials(bar*v1, partials+num_args1);
1407 }
1408
1410 void getTangents(int i, value_type dots[]) const {
1411 expr1.getTangents(i, dots);
1412 expr2.getTangents(i, dots+num_args1);
1413 }
1414
1415 template <int Arg>
1417 value_type getTangent(int i) const {
1418 if (Arg < num_args1)
1419 return expr1.template getTangent<Arg>(i);
1420 else
1421 return expr2.template getTangent<Arg-num_args1>(i);
1422 }
1423
1425 bool isLinear() const {
1426 return false;
1427 }
1428
1430 bool hasFastAccess() const {
1431 return expr1.hasFastAccess() && expr2.hasFastAccess();
1432 }
1433
1435 const value_type dx(int i) const {
1436 if (expr1.size() > 0 && expr2.size() > 0)
1437 return v1*expr2.dx(i) + expr1.dx(i)*v2;
1438 else if (expr1.size() > 0)
1439 return expr1.dx(i)*v2;
1440 else
1441 return v1*expr2.dx(i);
1442 }
1443
1445 const value_type fastAccessDx(int i) const {
1446 return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1447 }
1448
1450 const value_type* getDx(int j) const {
1451 if (j < num_args1)
1452 return expr1.getDx(j);
1453 else
1454 return expr2.getDx(j-num_args1);
1455 }
1456
1457 protected:
1458
1459 const ExprT1& expr1;
1460 const ExprT2& expr2;
1461 mutable value_type_1 v1;
1462 mutable value_type_2 v2;
1463
1464 };
1465
1466 template <typename ExprT1, typename T2>
1467 class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1468
1469 public:
1470
1471 typedef ConstExpr<T2> ExprT2;
1472 typedef typename ExprT1::value_type value_type_1;
1473 typedef typename ExprT2::value_type value_type_2;
1474 typedef typename Sacado::Promote<value_type_1,
1475 value_type_2>::type value_type;
1476 typedef typename ExprT1::scalar_type scalar_type_1;
1477 typedef typename ExprT2::scalar_type scalar_type_2;
1478 typedef typename Sacado::Promote<scalar_type_1,
1479 scalar_type_2>::type scalar_type;
1480
1481 typedef typename ExprT1::base_expr_type base_expr_type_1;
1482 typedef typename ExprT2::base_expr_type base_expr_type_2;
1483 typedef typename Sacado::Promote<base_expr_type_1,
1484 base_expr_type_2>::type base_expr_type;
1485
1486 static const int num_args = ExprT1::num_args;
1487
1488 static const bool is_linear = ExprT1::is_linear;
1489
1491 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1492 expr1(expr1_), expr2(expr2_) {}
1493
1495 int size() const {
1496 return expr1.size();
1497 }
1498
1499 template <int Arg>
1501 bool isActive() const {
1502 return expr1.template isActive<Arg>();
1503 }
1504
1506 bool updateValue() const {
1507 return expr1.updateValue();
1508 }
1509
1511 void cache() const {
1512 expr1.cache();
1513 }
1514
1516 value_type val() const {
1517 return expr1.val()*expr2.val();
1518 }
1519
1521 void computePartials(const value_type& bar,
1522 value_type partials[]) const {
1523 expr1.computePartials(bar*expr2.val(), partials);
1524 }
1525
1527 void getTangents(int i, value_type dots[]) const {
1528 expr1.getTangents(i, dots);
1529 }
1530
1531 template <int Arg>
1533 value_type getTangent(int i) const {
1534 return expr1.template getTangent<Arg>(i);
1535 }
1536
1538 bool isLinear() const {
1539 return expr1.isLinear();
1540 }
1541
1543 bool hasFastAccess() const {
1544 return expr1.hasFastAccess();
1545 }
1546
1548 const value_type dx(int i) const {
1549 return expr1.dx(i)*expr2.val();
1550 }
1551
1553 const value_type fastAccessDx(int i) const {
1554 return expr1.fastAccessDx(i)*expr2.val();
1555 }
1556
1558 const value_type* getDx(int j) const {
1559 return expr1.getDx(j);
1560 }
1561
1562 protected:
1563
1564 const ExprT1& expr1;
1565 ExprT2 expr2;
1566
1567 };
1568
1569 template <typename T1, typename ExprT2>
1570 class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1571
1572 public:
1573
1574 typedef ConstExpr<T1> ExprT1;
1575 typedef typename ExprT1::value_type value_type_1;
1576 typedef typename ExprT2::value_type value_type_2;
1577 typedef typename Sacado::Promote<value_type_1,
1578 value_type_2>::type value_type;
1579 typedef typename ExprT1::scalar_type scalar_type_1;
1580 typedef typename ExprT2::scalar_type scalar_type_2;
1581 typedef typename Sacado::Promote<scalar_type_1,
1582 scalar_type_2>::type scalar_type;
1583
1584 typedef typename ExprT1::base_expr_type base_expr_type_1;
1585 typedef typename ExprT2::base_expr_type base_expr_type_2;
1586 typedef typename Sacado::Promote<base_expr_type_1,
1587 base_expr_type_2>::type base_expr_type;
1588
1589 static const int num_args = ExprT2::num_args;
1590
1591 static const bool is_linear = ExprT2::is_linear;
1592
1594 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1595 expr1(expr1_), expr2(expr2_) {}
1596
1598 int size() const {
1599 return expr2.size();
1600 }
1601
1602 template <int Arg>
1604 bool isActive() const {
1605 return expr2.template isActive<Arg>();
1606 }
1607
1609 bool updateValue() const {
1610 return expr2.updateValue();
1611 }
1612
1614 void cache() const {
1615 expr2.cache();
1616 }
1617
1619 value_type val() const {
1620 return expr1.val()*expr2.val();
1621 }
1622
1624 void computePartials(const value_type& bar,
1625 value_type partials[]) const {
1626 expr2.computePartials(bar*expr1.val(), partials);
1627 }
1628
1630 void getTangents(int i, value_type dots[]) const {
1631 expr2.getTangents(i, dots);
1632 }
1633
1634 template <int Arg>
1636 value_type getTangent(int i) const {
1637 return expr2.template getTangent<Arg>(i);
1638 }
1639
1641 bool isLinear() const {
1642 return expr2.isLinear();
1643 }
1644
1646 bool hasFastAccess() const {
1647 return expr2.hasFastAccess();
1648 }
1649
1651 const value_type dx(int i) const {
1652 return expr1.val()*expr2.dx(i);
1653 }
1654
1656 const value_type fastAccessDx(int i) const {
1657 return expr1.val()*expr2.fastAccessDx(i);
1658 }
1659
1661 const value_type* getDx(int j) const {
1662 return expr2.getDx(j);
1663 }
1664
1665 protected:
1666
1667 ExprT1 expr1;
1668 const ExprT2& expr2;
1669
1670 };
1671
1672 //
1673 // DivisionOp
1674 //
1675
1676 template <typename ExprT1, typename ExprT2>
1677 class DivisionOp {};
1678
1679 template <typename ExprT1, typename ExprT2>
1680 class Expr< DivisionOp<ExprT1,ExprT2> > {
1681
1682 public:
1683
1684 typedef typename ExprT1::value_type value_type_1;
1685 typedef typename ExprT2::value_type value_type_2;
1686 typedef typename Sacado::Promote<value_type_1,
1687 value_type_2>::type value_type;
1688 typedef typename ExprT1::scalar_type scalar_type_1;
1689 typedef typename ExprT2::scalar_type scalar_type_2;
1690 typedef typename Sacado::Promote<scalar_type_1,
1691 scalar_type_2>::type scalar_type;
1692
1693 typedef typename ExprT1::base_expr_type base_expr_type_1;
1694 typedef typename ExprT2::base_expr_type base_expr_type_2;
1695 typedef typename Sacado::Promote<base_expr_type_1,
1696 base_expr_type_2>::type base_expr_type;
1697
1698 static const int num_args1 = ExprT1::num_args;
1699 static const int num_args2 = ExprT2::num_args;
1700 static const int num_args = num_args1 + num_args2;
1701
1702 static const bool is_linear = false;
1703
1705 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1706 expr1(expr1_), expr2(expr2_) {}
1707
1709 int size() const {
1710 int sz1 = expr1.size(), sz2 = expr2.size();
1711 return sz1 > sz2 ? sz1 : sz2;
1712 }
1713
1714 template <int Arg>
1716 bool isActive() const {
1717 if (Arg < num_args1)
1718 return expr1.template isActive<Arg>();
1719 else
1720 return expr2.template isActive<Arg-num_args1>();
1721 }
1722
1724 bool updateValue() const {
1725 return expr1.updateValue() && expr2.updateValue();
1726 }
1727
1729 void cache() const {
1730 expr1.cache();
1731 expr2.cache();
1732 const value_type_1 v1 = expr1.val();
1733 const value_type_2 v2 = expr2.val();
1734 a = scalar_type(1.0)/v2;
1735 v = v1*a;
1736 b = -v/v2;
1737 }
1738
1740 value_type val() const {
1741 return v;
1742 }
1743
1745 void computePartials(const value_type& bar,
1746 value_type partials[]) const {
1747 if (num_args1 > 0)
1748 expr1.computePartials(bar*a, partials);
1749 if (num_args2 > 0)
1750 expr2.computePartials(bar*b, partials+num_args1);
1751 }
1752
1754 void getTangents(int i, value_type dots[]) const {
1755 expr1.getTangents(i, dots);
1756 expr2.getTangents(i, dots+num_args1);
1757 }
1758
1759 template <int Arg>
1761 value_type getTangent(int i) const {
1762 if (Arg < num_args1)
1763 return expr1.template getTangent<Arg>(i);
1764 else
1765 return expr2.template getTangent<Arg-num_args1>(i);
1766 }
1767
1769 bool isLinear() const {
1770 return false;
1771 }
1772
1774 bool hasFastAccess() const {
1775 return expr1.hasFastAccess() && expr2.hasFastAccess();
1776 }
1777
1779 const value_type dx(int i) const {
1780 if (expr1.size() > 0 && expr2.size() > 0)
1781 return expr1.dx(i)*a + expr2.dx(i)*b;
1782 else if (expr1.size() > 0)
1783 return expr1.dx(i)*a;
1784 else
1785 return expr1.val()*b;
1786 }
1787
1789 const value_type fastAccessDx(int i) const {
1790 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1791 }
1792
1794 const value_type* getDx(int j) const {
1795 if (j < num_args1)
1796 return expr1.getDx(j);
1797 else
1798 return expr2.getDx(j-num_args1);
1799 }
1800
1801 protected:
1802
1803 const ExprT1& expr1;
1804 const ExprT2& expr2;
1805 mutable value_type v;
1806 mutable value_type a;
1807 mutable value_type b;
1808
1809 };
1810
1811 template <typename ExprT1, typename T2>
1812 class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1813
1814 public:
1815
1816 typedef ConstExpr<T2> ExprT2;
1817 typedef typename ExprT1::value_type value_type_1;
1818 typedef typename ExprT2::value_type value_type_2;
1819 typedef typename Sacado::Promote<value_type_1,
1820 value_type_2>::type value_type;
1821 typedef typename ExprT1::scalar_type scalar_type_1;
1822 typedef typename ExprT2::scalar_type scalar_type_2;
1823 typedef typename Sacado::Promote<scalar_type_1,
1824 scalar_type_2>::type scalar_type;
1825
1826 typedef typename ExprT1::base_expr_type base_expr_type_1;
1827 typedef typename ExprT2::base_expr_type base_expr_type_2;
1828 typedef typename Sacado::Promote<base_expr_type_1,
1829 base_expr_type_2>::type base_expr_type;
1830
1831 static const int num_args = ExprT1::num_args;
1832
1833 static const bool is_linear = ExprT1::is_linear;
1834
1836 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1837 expr1(expr1_), expr2(expr2_) {}
1838
1840 int size() const {
1841 return expr1.size();
1842 }
1843
1844 template <int Arg>
1846 bool isActive() const {
1847 return expr1.template isActive<Arg>();
1848 }
1849
1851 bool updateValue() const {
1852 return expr1.updateValue();
1853 }
1854
1856 void cache() const {
1857 expr1.cache();
1858 const value_type_1 v1 = expr1.val();
1859 a = scalar_type(1.0)/expr2.val();
1860 v = v1*a;
1861 }
1862
1864 value_type val() const {
1865 return v;
1866 }
1867
1869 void computePartials(const value_type& bar,
1870 value_type partials[]) const {
1871 expr1.computePartials(bar*a, partials);
1872 }
1873
1875 void getTangents(int i, value_type dots[]) const {
1876 expr1.getTangents(i, dots);
1877 }
1878
1879 template <int Arg>
1881 value_type getTangent(int i) const {
1882 return expr1.template getTangent<Arg>(i);
1883 }
1884
1886 bool isLinear() const {
1887 return expr1.isLinear();
1888 }
1889
1891 bool hasFastAccess() const {
1892 return expr1.hasFastAccess();
1893 }
1894
1896 const value_type dx(int i) const {
1897 return expr1.dx(i)*a;
1898 }
1899
1901 const value_type fastAccessDx(int i) const {
1902 return expr1.fastAccessDx(i)*a;
1903 }
1904
1906 const value_type* getDx(int j) const {
1907 return expr1.getDx(j);
1908 }
1909
1910 protected:
1911
1912 const ExprT1& expr1;
1913 ExprT2 expr2;
1914 mutable value_type v;
1915 mutable value_type a;
1916
1917 };
1918
1919 template <typename T1, typename ExprT2>
1920 class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1921
1922 public:
1923
1924 typedef ConstExpr<T1> ExprT1;
1925 typedef typename ExprT1::value_type value_type_1;
1926 typedef typename ExprT2::value_type value_type_2;
1927 typedef typename Sacado::Promote<value_type_1,
1928 value_type_2>::type value_type;
1929 typedef typename ExprT1::scalar_type scalar_type_1;
1930 typedef typename ExprT2::scalar_type scalar_type_2;
1931 typedef typename Sacado::Promote<scalar_type_1,
1932 scalar_type_2>::type scalar_type;
1933
1934 typedef typename ExprT1::base_expr_type base_expr_type_1;
1935 typedef typename ExprT2::base_expr_type base_expr_type_2;
1936 typedef typename Sacado::Promote<base_expr_type_1,
1937 base_expr_type_2>::type base_expr_type;
1938
1939 static const int num_args = ExprT2::num_args;
1940
1941 static const bool is_linear = false;
1942
1944 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1945 expr1(expr1_), expr2(expr2_) {}
1946
1948 int size() const {
1949 return expr2.size();
1950 }
1951
1952 template <int Arg>
1954 bool isActive() const {
1955 return expr2.template isActive<Arg>();
1956 }
1957
1959 bool updateValue() const {
1960 return expr2.updateValue();
1961 }
1962
1964 void cache() const {
1965 expr2.cache();
1966 const value_type_2 v2 = expr2.val();
1967 v = expr1.val()/v2;
1968 b = -v/v2;
1969 }
1970
1972 value_type val() const {
1973 return v;
1974 }
1975
1977 void computePartials(const value_type& bar,
1978 value_type partials[]) const {
1979 expr2.computePartials(bar*b, partials);
1980 }
1981
1983 void getTangents(int i, value_type dots[]) const {
1984 expr2.getTangents(i, dots);
1985 }
1986
1987 template <int Arg>
1989 value_type getTangent(int i) const {
1990 return expr2.template getTangent<Arg>(i);
1991 }
1992
1994 bool isLinear() const {
1995 return false;
1996 }
1997
1999 bool hasFastAccess() const {
2000 return expr2.hasFastAccess();
2001 }
2002
2004 const value_type dx(int i) const {
2005 return expr2.dx(i)*b;
2006 }
2007
2009 const value_type fastAccessDx(int i) const {
2010 return expr2.fastAccessDx(i)*b;
2011 }
2012
2014 const value_type* getDx(int j) const {
2015 return expr2.getDx(j);
2016 }
2017
2018 protected:
2019
2020 ExprT1 expr1;
2021 const ExprT2& expr2;
2022 mutable value_type v;
2023 mutable value_type b;
2024
2025 };
2026
2027 //
2028 // Atan2Op
2029 //
2030
2031 template <typename ExprT1, typename ExprT2>
2032 class Atan2Op {};
2033
2034 template <typename ExprT1, typename ExprT2>
2035 class Expr< Atan2Op<ExprT1,ExprT2> > {
2036
2037 public:
2038
2039 typedef typename ExprT1::value_type value_type_1;
2040 typedef typename ExprT2::value_type value_type_2;
2041 typedef typename Sacado::Promote<value_type_1,
2042 value_type_2>::type value_type;
2043 typedef typename ExprT1::scalar_type scalar_type_1;
2044 typedef typename ExprT2::scalar_type scalar_type_2;
2045 typedef typename Sacado::Promote<scalar_type_1,
2046 scalar_type_2>::type scalar_type;
2047
2048 typedef typename ExprT1::base_expr_type base_expr_type_1;
2049 typedef typename ExprT2::base_expr_type base_expr_type_2;
2050 typedef typename Sacado::Promote<base_expr_type_1,
2051 base_expr_type_2>::type base_expr_type;
2052
2053 static const int num_args1 = ExprT1::num_args;
2054 static const int num_args2 = ExprT2::num_args;
2055 static const int num_args = num_args1 + num_args2;
2056
2057 static const bool is_linear = false;
2058
2060 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2061 expr1(expr1_), expr2(expr2_) {}
2062
2064 int size() const {
2065 int sz1 = expr1.size(), sz2 = expr2.size();
2066 return sz1 > sz2 ? sz1 : sz2;
2067 }
2068
2069 template <int Arg>
2071 bool isActive() const {
2072 if (Arg < num_args1)
2073 return expr1.template isActive<Arg>();
2074 else
2075 return expr2.template isActive<Arg-num_args1>();
2076 }
2077
2079 bool updateValue() const {
2080 return expr1.updateValue() && expr2.updateValue();
2081 }
2082
2084 void cache() const {
2085 expr1.cache();
2086 expr2.cache();
2087 const value_type_1 v1 = expr1.val();
2088 const value_type_2 v2 = expr2.val();
2089 a = scalar_type(1.0)/(v1*v1 + v2*v2);
2090 b = -v1*a;
2091 a = v2*a;
2092 v = std::atan2(v1,v2);
2093 }
2094
2096 value_type val() const {
2097 return v;
2098 }
2099
2101 void computePartials(const value_type& bar,
2102 value_type partials[]) const {
2103 if (num_args1 > 0)
2104 expr1.computePartials(bar*a, partials);
2105 if (num_args2 > 0)
2106 expr2.computePartials(bar*b, partials+num_args1);
2107 }
2108
2110 void getTangents(int i, value_type dots[]) const {
2111 expr1.getTangents(i, dots);
2112 expr2.getTangents(i, dots+num_args1);
2113 }
2114
2115 template <int Arg>
2117 value_type getTangent(int i) const {
2118 if (Arg < num_args1)
2119 return expr1.template getTangent<Arg>(i);
2120 else
2121 return expr2.template getTangent<Arg-num_args1>(i);
2122 }
2123
2125 bool isLinear() const {
2126 return false;
2127 }
2128
2130 bool hasFastAccess() const {
2131 return expr1.hasFastAccess() && expr2.hasFastAccess();
2132 }
2133
2135 const value_type dx(int i) const {
2136 if (expr1.size() > 0 && expr2.size() > 0)
2137 return expr1.dx(i)*a + expr2.dx(i)*b;
2138 else if (expr1.size() > 0)
2139 return expr1.dx(i)*a;
2140 else
2141 return expr1.val()*b;
2142 }
2143
2145 const value_type fastAccessDx(int i) const {
2146 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
2147 }
2148
2150 const value_type* getDx(int j) const {
2151 if (j < num_args1)
2152 return expr1.getDx(j);
2153 else
2154 return expr2.getDx(j-num_args1);
2155 }
2156
2157 protected:
2158
2159 const ExprT1& expr1;
2160 const ExprT2& expr2;
2161 mutable value_type v;
2162 mutable value_type a;
2163 mutable value_type b;
2164
2165 };
2166
2167 template <typename ExprT1, typename T2>
2168 class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
2169
2170 public:
2171
2172 typedef ConstExpr<T2> ExprT2;
2173 typedef typename ExprT1::value_type value_type_1;
2174 typedef typename ExprT2::value_type value_type_2;
2175 typedef typename Sacado::Promote<value_type_1,
2176 value_type_2>::type value_type;
2177 typedef typename ExprT1::scalar_type scalar_type_1;
2178 typedef typename ExprT2::scalar_type scalar_type_2;
2179 typedef typename Sacado::Promote<scalar_type_1,
2180 scalar_type_2>::type scalar_type;
2181
2182 typedef typename ExprT1::base_expr_type base_expr_type_1;
2183 typedef typename ExprT2::base_expr_type base_expr_type_2;
2184 typedef typename Sacado::Promote<base_expr_type_1,
2185 base_expr_type_2>::type base_expr_type;
2186
2187 static const int num_args = ExprT1::num_args;
2188
2189 static const bool is_linear = false;
2190
2192 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2193 expr1(expr1_), expr2(expr2_) {}
2194
2196 int size() const {
2197 return expr1.size();
2198 }
2199
2200 template <int Arg>
2202 bool isActive() const {
2203 return expr1.template isActive<Arg>();
2204 }
2205
2207 bool updateValue() const {
2208 return expr1.updateValue();
2209 }
2210
2212 void cache() const {
2213 expr1.cache();
2214 const value_type_1 v1 = expr1.val();
2215 const value_type_2 v2 = expr2.val();
2216 a = v2/(v1*v1 + v2*v2);
2217 v = std::atan2(v1,v2);
2218 }
2219
2221 value_type val() const {
2222 return v;
2223 }
2224
2226 void computePartials(const value_type& bar,
2227 value_type partials[]) const {
2228 expr1.computePartials(bar*a, partials);
2229 }
2230
2232 void getTangents(int i, value_type dots[]) const {
2233 expr1.getTangents(i, dots);
2234 }
2235
2236 template <int Arg>
2238 value_type getTangent(int i) const {
2239 return expr1.template getTangent<Arg>(i);
2240 }
2241
2243 bool isLinear() const {
2244 return false;
2245 }
2246
2248 bool hasFastAccess() const {
2249 return expr1.hasFastAccess();
2250 }
2251
2253 const value_type dx(int i) const {
2254 return expr1.dx(i)*a;
2255 }
2256
2258 const value_type fastAccessDx(int i) const {
2259 return expr1.fastAccessDx(i)*a;
2260 }
2261
2263 const value_type* getDx(int j) const {
2264 return expr1.getDx(j);
2265 }
2266
2267 protected:
2268
2269 const ExprT1& expr1;
2270 ExprT2 expr2;
2271 mutable value_type v;
2272 mutable value_type a;
2273
2274 };
2275
2276 template <typename T1, typename ExprT2>
2277 class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
2278
2279 public:
2280
2281 typedef ConstExpr<T1> ExprT1;
2282 typedef typename ExprT1::value_type value_type_1;
2283 typedef typename ExprT2::value_type value_type_2;
2284 typedef typename Sacado::Promote<value_type_1,
2285 value_type_2>::type value_type;
2286 typedef typename ExprT1::scalar_type scalar_type_1;
2287 typedef typename ExprT2::scalar_type scalar_type_2;
2288 typedef typename Sacado::Promote<scalar_type_1,
2289 scalar_type_2>::type scalar_type;
2290
2291 typedef typename ExprT1::base_expr_type base_expr_type_1;
2292 typedef typename ExprT2::base_expr_type base_expr_type_2;
2293 typedef typename Sacado::Promote<base_expr_type_1,
2294 base_expr_type_2>::type base_expr_type;
2295
2296 static const int num_args = ExprT2::num_args;
2297
2298 static const bool is_linear = false;
2299
2301 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2302 expr1(expr1_), expr2(expr2_) {}
2303
2305 int size() const {
2306 return expr2.size();
2307 }
2308
2309 template <int Arg>
2311 bool isActive() const {
2312 return expr2.template isActive<Arg>();
2313 }
2314
2316 bool updateValue() const {
2317 return expr2.updateValue();
2318 }
2319
2321 void cache() const {
2322 expr2.cache();
2323 const value_type_1 v1 = expr1.val();
2324 const value_type_2 v2 = expr2.val();
2325 b = -v1/(v1*v1 + v2*v2);
2326 v = std::atan2(v1,v2);
2327 }
2328
2330 value_type val() const {
2331 return v;
2332 }
2333
2335 void computePartials(const value_type& bar,
2336 value_type partials[]) const {
2337 expr2.computePartials(bar*b, partials);
2338 }
2339
2341 void getTangents(int i, value_type dots[]) const {
2342 expr2.getTangents(i, dots);
2343 }
2344
2345 template <int Arg>
2347 value_type getTangent(int i) const {
2348 return expr2.template getTangent<Arg>(i);
2349 }
2350
2352 bool isLinear() const {
2353 return false;
2354 }
2355
2357 bool hasFastAccess() const {
2358 return expr2.hasFastAccess();
2359 }
2360
2362 const value_type dx(int i) const {
2363 return expr2.dx(i)*b;
2364 }
2365
2367 const value_type fastAccessDx(int i) const {
2368 return expr2.fastAccessDx(i)*b;
2369 }
2370
2372 const value_type* getDx(int j) const {
2373 return expr2.getDx(j);
2374 }
2375
2376 protected:
2377
2378 ExprT1 expr1;
2379 const ExprT2& expr2;
2380 mutable value_type v;
2381 mutable value_type b;
2382
2383 };
2384
2385 //
2386 // PowerOp
2387 //
2388
2389 template <typename ExprT1, typename ExprT2>
2390 class PowerOp {};
2391
2392 template <typename ExprT1, typename ExprT2>
2393 class Expr< PowerOp<ExprT1,ExprT2> > {
2394
2395 public:
2396
2397 typedef typename ExprT1::value_type value_type_1;
2398 typedef typename ExprT2::value_type value_type_2;
2399 typedef typename Sacado::Promote<value_type_1,
2400 value_type_2>::type value_type;
2401 typedef typename ExprT1::scalar_type scalar_type_1;
2402 typedef typename ExprT2::scalar_type scalar_type_2;
2403 typedef typename Sacado::Promote<scalar_type_1,
2404 scalar_type_2>::type scalar_type;
2405
2406 typedef typename ExprT1::base_expr_type base_expr_type_1;
2407 typedef typename ExprT2::base_expr_type base_expr_type_2;
2408 typedef typename Sacado::Promote<base_expr_type_1,
2409 base_expr_type_2>::type base_expr_type;
2410
2411 static const int num_args1 = ExprT1::num_args;
2412 static const int num_args2 = ExprT2::num_args;
2413 static const int num_args = num_args1 + num_args2;
2414
2415 static const bool is_linear = false;
2416
2418 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2419 expr1(expr1_), expr2(expr2_) {}
2420
2422 int size() const {
2423 int sz1 = expr1.size(), sz2 = expr2.size();
2424 return sz1 > sz2 ? sz1 : sz2;
2425 }
2426
2427 template <int Arg>
2429 bool isActive() const {
2430 if (Arg < num_args1)
2431 return expr1.template isActive<Arg>();
2432 else
2433 return expr2.template isActive<Arg-num_args1>();
2434 }
2435
2437 bool updateValue() const {
2438 return expr1.updateValue() && expr2.updateValue();
2439 }
2440
2442 void cache() const {
2443 expr1.cache();
2444 expr2.cache();
2445 const value_type_1 v1 = expr1.val();
2446 const value_type_2 v2 = expr2.val();
2447 v = std::pow(v1,v2);
2448 if (expr2.size() == 0 && v2 == scalar_type(1.0)) {
2449 a = scalar_type(1.0);
2450 b = scalar_type(0.0);
2451 }
2452 else if (v1 == scalar_type(0.0)) {
2453 a = scalar_type(0.0);
2454 b = scalar_type(0.0);
2455 }
2456 else {
2457 a = v*v2/v1;
2458 b = v*std::log(v1);
2459 }
2460 }
2461
2463 value_type val() const {
2464 return v;
2465 }
2466
2468 void computePartials(const value_type& bar,
2469 value_type partials[]) const {
2470 if (num_args1 > 0)
2471 expr1.computePartials(bar*a, partials);
2472 if (num_args2 > 0)
2473 expr2.computePartials(bar*b, partials+num_args1);
2474 }
2475
2477 void getTangents(int i, value_type dots[]) const {
2478 expr1.getTangents(i, dots);
2479 expr2.getTangents(i, dots+num_args1);
2480 }
2481
2482 template <int Arg>
2484 value_type getTangent(int i) const {
2485 if (Arg < num_args1)
2486 return expr1.template getTangent<Arg>(i);
2487 else
2488 return expr2.template getTangent<Arg-num_args1>(i);
2489 }
2490
2492 bool isLinear() const {
2493 return false;
2494 }
2495
2497 bool hasFastAccess() const {
2498 return expr1.hasFastAccess() && expr2.hasFastAccess();
2499 }
2500
2502 const value_type dx(int i) const {
2503 if (expr1.size() > 0 && expr2.size() > 0)
2504 return expr1.dx(i)*a + expr2.dx(i)*b;
2505 else if (expr1.size() > 0)
2506 return expr1.dx(i)*a;
2507 else
2508 return expr1.val()*b;
2509 }
2510
2512 const value_type fastAccessDx(int i) const {
2513 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
2514 }
2515
2517 const value_type* getDx(int j) const {
2518 if (j < num_args1)
2519 return expr1.getDx(j);
2520 else
2521 return expr2.getDx(j-num_args1);
2522 }
2523
2524 protected:
2525
2526 const ExprT1& expr1;
2527 const ExprT2& expr2;
2528 mutable value_type v;
2529 mutable value_type a;
2530 mutable value_type b;
2531
2532 };
2533
2534 template <typename ExprT1, typename T2>
2535 class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
2536
2537 public:
2538
2539 typedef ConstExpr<T2> ExprT2;
2540 typedef typename ExprT1::value_type value_type_1;
2541 typedef typename ExprT2::value_type value_type_2;
2542 typedef typename Sacado::Promote<value_type_1,
2543 value_type_2>::type value_type;
2544 typedef typename ExprT1::scalar_type scalar_type_1;
2545 typedef typename ExprT2::scalar_type scalar_type_2;
2546 typedef typename Sacado::Promote<scalar_type_1,
2547 scalar_type_2>::type scalar_type;
2548
2549 typedef typename ExprT1::base_expr_type base_expr_type_1;
2550 typedef typename ExprT2::base_expr_type base_expr_type_2;
2551 typedef typename Sacado::Promote<base_expr_type_1,
2552 base_expr_type_2>::type base_expr_type;
2553
2554 static const int num_args = ExprT1::num_args;
2555
2556 static const bool is_linear = false;
2557
2559 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2560 expr1(expr1_), expr2(expr2_) {}
2561
2563 int size() const {
2564 return expr1.size();
2565 }
2566
2567 template <int Arg>
2569 bool isActive() const {
2570 return expr1.template isActive<Arg>();
2571 }
2572
2574 bool updateValue() const {
2575 return expr1.updateValue();
2576 }
2577
2579 void cache() const {
2580 expr1.cache();
2581 const value_type_1 v1 = expr1.val();
2582 const value_type_2 v2 = expr2.val();
2583 v = std::pow(v1,v2);
2584 if (v2 == scalar_type(1.0)) {
2585 a = scalar_type(1.0);
2586 }
2587 else if (v1 == scalar_type(0.0)) {
2588 a = scalar_type(0.0);
2589 }
2590 else {
2591 a = v*v2/v1;
2592 }
2593 }
2594
2596 value_type val() const {
2597 return v;
2598 }
2599
2601 void computePartials(const value_type& bar,
2602 value_type partials[]) const {
2603 expr1.computePartials(bar*a, partials);
2604 }
2605
2607 void getTangents(int i, value_type dots[]) const {
2608 expr1.getTangents(i, dots);
2609 }
2610
2611 template <int Arg>
2613 value_type getTangent(int i) const {
2614 return expr1.template getTangent<Arg>(i);
2615 }
2616
2618 bool isLinear() const {
2619 return false;
2620 }
2621
2623 bool hasFastAccess() const {
2624 return expr1.hasFastAccess();
2625 }
2626
2628 const value_type dx(int i) const {
2629 return expr1.dx(i)*a;
2630 }
2631
2633 const value_type fastAccessDx(int i) const {
2634 return expr1.fastAccessDx(i)*a;
2635 }
2636
2638 const value_type* getDx(int j) const {
2639 return expr1.getDx(j);
2640 }
2641
2642 protected:
2643
2644 const ExprT1& expr1;
2645 ExprT2 expr2;
2646 mutable value_type v;
2647 mutable value_type a;
2648
2649 };
2650
2651 template <typename T1, typename ExprT2>
2652 class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
2653
2654 public:
2655
2656 typedef ConstExpr<T1> ExprT1;
2657 typedef typename ExprT1::value_type value_type_1;
2658 typedef typename ExprT2::value_type value_type_2;
2659 typedef typename Sacado::Promote<value_type_1,
2660 value_type_2>::type value_type;
2661 typedef typename ExprT1::scalar_type scalar_type_1;
2662 typedef typename ExprT2::scalar_type scalar_type_2;
2663 typedef typename Sacado::Promote<scalar_type_1,
2664 scalar_type_2>::type scalar_type;
2665
2666 typedef typename ExprT1::base_expr_type base_expr_type_1;
2667 typedef typename ExprT2::base_expr_type base_expr_type_2;
2668 typedef typename Sacado::Promote<base_expr_type_1,
2669 base_expr_type_2>::type base_expr_type;
2670
2671 static const int num_args = ExprT2::num_args;
2672
2673 static const bool is_linear = false;
2674
2676 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2677 expr1(expr1_), expr2(expr2_) {}
2678
2680 int size() const {
2681 return expr2.size();
2682 }
2683
2684 template <int Arg>
2686 bool isActive() const {
2687 return expr2.template isActive<Arg>();
2688 }
2689
2691 bool updateValue() const {
2692 return expr2.updateValue();
2693 }
2694
2696 void cache() const {
2697 expr2.cache();
2698 const value_type_1 v1 = expr1.val();
2699 const value_type_2 v2 = expr2.val();
2700 v = std::pow(v1,v2);
2701 if (v1 == scalar_type(0.0)) {
2702 b = scalar_type(0.0);
2703 }
2704 else {
2705 b = v*std::log(v1);
2706 }
2707 }
2708
2710 value_type val() const {
2711 return v;
2712 }
2713
2715 void computePartials(const value_type& bar,
2716 value_type partials[]) const {
2717 expr2.computePartials(bar*b, partials);
2718 }
2719
2721 void getTangents(int i, value_type dots[]) const {
2722 expr2.getTangents(i, dots);
2723 }
2724
2725 template <int Arg>
2727 value_type getTangent(int i) const {
2728 return expr2.template getTangent<Arg>(i);
2729 }
2730
2732 bool isLinear() const {
2733 return false;
2734 }
2735
2737 bool hasFastAccess() const {
2738 return expr2.hasFastAccess();
2739 }
2740
2742 const value_type dx(int i) const {
2743 return expr2.dx(i)*b;
2744 }
2745
2747 const value_type fastAccessDx(int i) const {
2748 return expr2.fastAccessDx(i)*b;
2749 }
2750
2752 const value_type* getDx(int j) const {
2753 return expr2.getDx(j);
2754 }
2755
2756 protected:
2757
2758 ExprT1 expr1;
2759 const ExprT2& expr2;
2760 mutable value_type v;
2761 mutable value_type b;
2762
2763 };
2764
2765 //
2766 // MaxOp
2767 //
2768
2769 template <typename ExprT1, typename ExprT2>
2770 class MaxOp {};
2771
2772 template <typename ExprT1, typename ExprT2>
2773 class Expr< MaxOp<ExprT1,ExprT2> > {
2774
2775 public:
2776
2777 typedef typename ExprT1::value_type value_type_1;
2778 typedef typename ExprT2::value_type value_type_2;
2779 typedef typename Sacado::Promote<value_type_1,
2780 value_type_2>::type value_type;
2781 typedef typename ExprT1::scalar_type scalar_type_1;
2782 typedef typename ExprT2::scalar_type scalar_type_2;
2783 typedef typename Sacado::Promote<scalar_type_1,
2784 scalar_type_2>::type scalar_type;
2785
2786 typedef typename ExprT1::base_expr_type base_expr_type_1;
2787 typedef typename ExprT2::base_expr_type base_expr_type_2;
2788 typedef typename Sacado::Promote<base_expr_type_1,
2789 base_expr_type_2>::type base_expr_type;
2790
2791 static const int num_args1 = ExprT1::num_args;
2792 static const int num_args2 = ExprT2::num_args;
2793 static const int num_args = num_args1 + num_args2;
2794
2795 static const bool is_linear = false;
2796
2798 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2799 expr1(expr1_), expr2(expr2_) {}
2800
2802 int size() const {
2803 int sz1 = expr1.size(), sz2 = expr2.size();
2804 return sz1 > sz2 ? sz1 : sz2;
2805 }
2806
2807 template <int Arg>
2809 bool isActive() const {
2810 if (Arg < num_args1)
2811 return expr1.template isActive<Arg>();
2812 else
2813 return expr2.template isActive<Arg-num_args1>();
2814 }
2815
2817 bool updateValue() const {
2818 return expr1.updateValue() && expr2.updateValue();
2819 }
2820
2822 void cache() const {
2823 expr1.cache();
2824 expr2.cache();
2825 const value_type_1 v1 = expr1.val();
2826 const value_type_2 v2 = expr2.val();
2827 max_v1 = (v1 >= v2);
2828 v = max_v1 ? v1 : v2;
2829 }
2830
2832 value_type val() const {
2833 return v;
2834 }
2835
2837 void computePartials(const value_type& bar,
2838 value_type partials[]) const {
2839 if (num_args1 > 0) {
2840 if (max_v1)
2841 expr1.computePartials(bar, partials);
2842 else
2843 expr1.computePartials(value_type(0.0), partials);
2844 }
2845 if (num_args2 > 0) {
2846 if (max_v1)
2847 expr2.computePartials(value_type(0.0), partials+num_args1);
2848 else
2849 expr2.computePartials(bar, partials+num_args1);
2850 }
2851 }
2852
2854 void getTangents(int i, value_type dots[]) const {
2855 expr1.getTangents(i, dots);
2856 expr2.getTangents(i, dots+num_args1);
2857 }
2858
2859 template <int Arg>
2861 value_type getTangent(int i) const {
2862 if (Arg < num_args1)
2863 return expr1.template getTangent<Arg>(i);
2864 else
2865 return expr2.template getTangent<Arg-num_args1>(i);
2866 }
2867
2869 bool isLinear() const {
2870 return false;
2871 }
2872
2874 bool hasFastAccess() const {
2875 return expr1.hasFastAccess() && expr2.hasFastAccess();
2876 }
2877
2879 const value_type dx(int i) const {
2880 return max_v1 ? expr1.dx(i) : expr2.dx(i);
2881 }
2882
2884 const value_type fastAccessDx(int i) const {
2885 return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2886 }
2887
2889 const value_type* getDx(int j) const {
2890 if (j < num_args1)
2891 return expr1.getDx(j);
2892 else
2893 return expr2.getDx(j-num_args1);
2894 }
2895
2896 protected:
2897
2898 const ExprT1& expr1;
2899 const ExprT2& expr2;
2900 mutable value_type v;
2901 mutable bool max_v1;
2902
2903 };
2904
2905 template <typename ExprT1, typename T2>
2906 class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2907
2908 public:
2909
2910 typedef ConstExpr<T2> ExprT2;
2911 typedef typename ExprT1::value_type value_type_1;
2912 typedef typename ExprT2::value_type value_type_2;
2913 typedef typename Sacado::Promote<value_type_1,
2914 value_type_2>::type value_type;
2915 typedef typename ExprT1::scalar_type scalar_type_1;
2916 typedef typename ExprT2::scalar_type scalar_type_2;
2917 typedef typename Sacado::Promote<scalar_type_1,
2918 scalar_type_2>::type scalar_type;
2919
2920 typedef typename ExprT1::base_expr_type base_expr_type_1;
2921 typedef typename ExprT2::base_expr_type base_expr_type_2;
2922 typedef typename Sacado::Promote<base_expr_type_1,
2923 base_expr_type_2>::type base_expr_type;
2924
2925 static const int num_args = ExprT1::num_args;
2926
2927 static const bool is_linear = false;
2928
2930 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2931 expr1(expr1_), expr2(expr2_) {}
2932
2934 int size() const {
2935 return expr1.size();
2936 }
2937
2938 template <int Arg>
2940 bool isActive() const {
2941 return expr1.template isActive<Arg>();
2942 }
2943
2945 bool updateValue() const {
2946 return expr1.updateValue();
2947 }
2948
2950 void cache() const {
2951 expr1.cache();
2952 const value_type_1 v1 = expr1.val();
2953 const value_type_2 v2 = expr2.val();
2954 max_v1 = (v1 >= v2);
2955 v = max_v1 ? v1 : v2;
2956 }
2957
2959 value_type val() const {
2960 return v;
2961 }
2962
2964 void computePartials(const value_type& bar,
2965 value_type partials[]) const {
2966 if (max_v1)
2967 expr1.computePartials(bar, partials);
2968 else
2969 expr1.computePartials(value_type(0.0), partials);
2970 }
2971
2973 void getTangents(int i, value_type dots[]) const {
2974 expr1.getTangents(i, dots);
2975 }
2976
2977 template <int Arg>
2979 value_type getTangent(int i) const {
2980 return expr1.template getTangent<Arg>(i);
2981 }
2982
2984 bool isLinear() const {
2985 return false;
2986 }
2987
2989 bool hasFastAccess() const {
2990 return expr1.hasFastAccess();
2991 }
2992
2994 const value_type dx(int i) const {
2995 return max_v1 ? expr1.dx(i) : value_type(0.0);
2996 }
2997
2999 const value_type fastAccessDx(int i) const {
3000 return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3001 }
3002
3004 const value_type* getDx(int j) const {
3005 return expr1.getDx(j);
3006 }
3007
3008 protected:
3009
3010 const ExprT1& expr1;
3011 ExprT2 expr2;
3012 mutable value_type v;
3013 mutable bool max_v1;
3014
3015 };
3016
3017 template <typename T1, typename ExprT2>
3018 class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
3019
3020 public:
3021
3022 typedef ConstExpr<T1> ExprT1;
3023 typedef typename ExprT1::value_type value_type_1;
3024 typedef typename ExprT2::value_type value_type_2;
3025 typedef typename Sacado::Promote<value_type_1,
3026 value_type_2>::type value_type;
3027 typedef typename ExprT1::scalar_type scalar_type_1;
3028 typedef typename ExprT2::scalar_type scalar_type_2;
3029 typedef typename Sacado::Promote<scalar_type_1,
3030 scalar_type_2>::type scalar_type;
3031
3032 typedef typename ExprT1::base_expr_type base_expr_type_1;
3033 typedef typename ExprT2::base_expr_type base_expr_type_2;
3034 typedef typename Sacado::Promote<base_expr_type_1,
3035 base_expr_type_2>::type base_expr_type;
3036
3037 static const int num_args = ExprT2::num_args;
3038
3039 static const bool is_linear = false;
3040
3042 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3043 expr1(expr1_), expr2(expr2_) {}
3044
3046 int size() const {
3047 return expr2.size();
3048 }
3049
3050 template <int Arg>
3052 bool isActive() const {
3053 return expr2.template isActive<Arg>();
3054 }
3055
3057 bool updateValue() const {
3058 return expr2.updateValue();
3059 }
3060
3062 void cache() const {
3063 expr2.cache();
3064 const value_type_1 v1 = expr1.val();
3065 const value_type_2 v2 = expr2.val();
3066 max_v1 = (v1 >= v2);
3067 v = max_v1 ? v1 : v2;
3068 }
3069
3071 value_type val() const {
3072 return v;
3073 }
3074
3076 void computePartials(const value_type& bar,
3077 value_type partials[]) const {
3078 if (max_v1)
3079 expr2.computePartials(value_type(0.0), partials);
3080 else
3081 expr2.computePartials(bar, partials);
3082 }
3083
3085 void getTangents(int i, value_type dots[]) const {
3086 expr2.getTangents(i, dots);
3087 }
3088
3089 template <int Arg>
3091 value_type getTangent(int i) const {
3092 return expr2.template getTangent<Arg>(i);
3093 }
3094
3096 bool isLinear() const {
3097 return false;
3098 }
3099
3101 bool hasFastAccess() const {
3102 return expr2.hasFastAccess();
3103 }
3104
3106 const value_type dx(int i) const {
3107 return max_v1 ? value_type(0.0) : expr2.dx(i);
3108 }
3109
3111 const value_type fastAccessDx(int i) const {
3112 return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3113 }
3114
3116 const value_type* getDx(int j) const {
3117 return expr2.getDx(j);
3118 }
3119
3120 protected:
3121
3122 ExprT1 expr1;
3123 const ExprT2& expr2;
3124 mutable value_type v;
3125 mutable bool max_v1;
3126
3127 };
3128
3129 //
3130 // MinOp
3131 //
3132
3133 template <typename ExprT1, typename ExprT2>
3134 class MinOp {};
3135
3136 template <typename ExprT1, typename ExprT2>
3137 class Expr< MinOp<ExprT1,ExprT2> > {
3138
3139 public:
3140
3141 typedef typename ExprT1::value_type value_type_1;
3142 typedef typename ExprT2::value_type value_type_2;
3143 typedef typename Sacado::Promote<value_type_1,
3144 value_type_2>::type value_type;
3145 typedef typename ExprT1::scalar_type scalar_type_1;
3146 typedef typename ExprT2::scalar_type scalar_type_2;
3147 typedef typename Sacado::Promote<scalar_type_1,
3148 scalar_type_2>::type scalar_type;
3149
3150 typedef typename ExprT1::base_expr_type base_expr_type_1;
3151 typedef typename ExprT2::base_expr_type base_expr_type_2;
3152 typedef typename Sacado::Promote<base_expr_type_1,
3153 base_expr_type_2>::type base_expr_type;
3154
3155 static const int num_args1 = ExprT1::num_args;
3156 static const int num_args2 = ExprT2::num_args;
3157 static const int num_args = num_args1 + num_args2;
3158
3159 static const bool is_linear = false;
3160
3162 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3163 expr1(expr1_), expr2(expr2_) {}
3164
3166 int size() const {
3167 int sz1 = expr1.size(), sz2 = expr2.size();
3168 return sz1 > sz2 ? sz1 : sz2;
3169 }
3170
3171 template <int Arg>
3173 bool isActive() const {
3174 if (Arg < num_args1)
3175 return expr1.template isActive<Arg>();
3176 else
3177 return expr2.template isActive<Arg-num_args1>();
3178 }
3179
3181 bool updateValue() const {
3182 return expr1.updateValue() && expr2.updateValue();
3183 }
3184
3186 void cache() const {
3187 expr1.cache();
3188 expr2.cache();
3189 const value_type_1 v1 = expr1.val();
3190 const value_type_2 v2 = expr2.val();
3191 min_v1 = (v1 <= v2);
3192 v = min_v1 ? v1 : v2;
3193 }
3194
3196 value_type val() const {
3197 return v;
3198 }
3199
3201 void computePartials(const value_type& bar,
3202 value_type partials[]) const {
3203 if (num_args1 > 0) {
3204 if (min_v1)
3205 expr1.computePartials(bar, partials);
3206 else
3207 expr1.computePartials(value_type(0.0), partials);
3208 }
3209 if (num_args2 > 0) {
3210 if (min_v1)
3211 expr2.computePartials(value_type(0.0), partials+num_args1);
3212 else
3213 expr2.computePartials(bar, partials+num_args1);
3214 }
3215 }
3216
3218 void getTangents(int i, value_type dots[]) const {
3219 expr1.getTangents(i, dots);
3220 expr2.getTangents(i, dots+num_args1);
3221 }
3222
3223 template <int Arg>
3225 value_type getTangent(int i) const {
3226 if (Arg < num_args1)
3227 return expr1.template getTangent<Arg>(i);
3228 else
3229 return expr2.template getTangent<Arg-num_args1>(i);
3230 }
3231
3233 bool isLinear() const {
3234 return false;
3235 }
3236
3238 bool hasFastAccess() const {
3239 return expr1.hasFastAccess() && expr2.hasFastAccess();
3240 }
3241
3243 const value_type dx(int i) const {
3244 return min_v1 ? expr1.dx(i) : expr2.dx(i);
3245 }
3246
3248 const value_type fastAccessDx(int i) const {
3249 return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
3250 }
3251
3253 const value_type* getDx(int j) const {
3254 if (j < num_args1)
3255 return expr1.getDx(j);
3256 else
3257 return expr2.getDx(j-num_args1);
3258 }
3259
3260 protected:
3261
3262 const ExprT1& expr1;
3263 const ExprT2& expr2;
3264 mutable value_type v;
3265 mutable bool min_v1;
3266
3267 };
3268
3269 template <typename ExprT1, typename T2>
3270 class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
3271
3272 public:
3273
3274 typedef ConstExpr<T2> ExprT2;
3275 typedef typename ExprT1::value_type value_type_1;
3276 typedef typename ExprT2::value_type value_type_2;
3277 typedef typename Sacado::Promote<value_type_1,
3278 value_type_2>::type value_type;
3279 typedef typename ExprT1::scalar_type scalar_type_1;
3280 typedef typename ExprT2::scalar_type scalar_type_2;
3281 typedef typename Sacado::Promote<scalar_type_1,
3282 scalar_type_2>::type scalar_type;
3283
3284 typedef typename ExprT1::base_expr_type base_expr_type_1;
3285 typedef typename ExprT2::base_expr_type base_expr_type_2;
3286 typedef typename Sacado::Promote<base_expr_type_1,
3287 base_expr_type_2>::type base_expr_type;
3288
3289 static const int num_args = ExprT1::num_args;
3290
3291 static const bool is_linear = false;
3292
3294 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3295 expr1(expr1_), expr2(expr2_) {}
3296
3298 int size() const {
3299 return expr1.size();
3300 }
3301
3302 template <int Arg>
3304 bool isActive() const {
3305 return expr1.template isActive<Arg>();
3306 }
3307
3309 bool updateValue() const {
3310 return expr1.updateValue();
3311 }
3312
3314 void cache() const {
3315 expr1.cache();
3316 const value_type_1 v1 = expr1.val();
3317 const value_type_2 v2 = expr2.val();
3318 min_v1 = (v1 <= v2);
3319 v = min_v1 ? v1 : v2;
3320 }
3321
3323 value_type val() const {
3324 return v;
3325 }
3326
3328 void computePartials(const value_type& bar,
3329 value_type partials[]) const {
3330 if (min_v1)
3331 expr1.computePartials(bar, partials);
3332 else
3333 expr1.computePartials(value_type(0.0), partials);
3334 }
3335
3337 void getTangents(int i, value_type dots[]) const {
3338 expr1.getTangents(i, dots);
3339 }
3340
3341 template <int Arg>
3343 value_type getTangent(int i) const {
3344 return expr1.template getTangent<Arg>(i);
3345 }
3346
3348 bool isLinear() const {
3349 return false;
3350 }
3351
3353 bool hasFastAccess() const {
3354 return expr1.hasFastAccess();
3355 }
3356
3358 const value_type dx(int i) const {
3359 return min_v1 ? expr1.dx(i) : value_type(0.0);
3360 }
3361
3363 const value_type fastAccessDx(int i) const {
3364 return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3365 }
3366
3368 const value_type* getDx(int j) const {
3369 return expr1.getDx(j);
3370 }
3371
3372 protected:
3373
3374 const ExprT1& expr1;
3375 ExprT2 expr2;
3376 mutable value_type v;
3377 mutable bool min_v1;
3378
3379 };
3380
3381 template <typename T1, typename ExprT2>
3382 class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
3383
3384 public:
3385
3386 typedef ConstExpr<T1> ExprT1;
3387 typedef typename ExprT1::value_type value_type_1;
3388 typedef typename ExprT2::value_type value_type_2;
3389 typedef typename Sacado::Promote<value_type_1,
3390 value_type_2>::type value_type;
3391 typedef typename ExprT1::scalar_type scalar_type_1;
3392 typedef typename ExprT2::scalar_type scalar_type_2;
3393 typedef typename Sacado::Promote<scalar_type_1,
3394 scalar_type_2>::type scalar_type;
3395
3396 typedef typename ExprT1::base_expr_type base_expr_type_1;
3397 typedef typename ExprT2::base_expr_type base_expr_type_2;
3398 typedef typename Sacado::Promote<base_expr_type_1,
3399 base_expr_type_2>::type base_expr_type;
3400
3401 static const int num_args = ExprT2::num_args;
3402
3403 static const bool is_linear = false;
3404
3406 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3407 expr1(expr1_), expr2(expr2_) {}
3408
3410 int size() const {
3411 return expr2.size();
3412 }
3413
3414 template <int Arg>
3416 bool isActive() const {
3417 return expr2.template isActive<Arg>();
3418 }
3419
3421 bool updateValue() const {
3422 return expr2.updateValue();
3423 }
3424
3426 void cache() const {
3427 expr2.cache();
3428 const value_type_1 v1 = expr1.val();
3429 const value_type_2 v2 = expr2.val();
3430 min_v1 = (v1 <= v2);
3431 v = min_v1 ? v1 : v2;
3432 }
3433
3435 value_type val() const {
3436 return v;
3437 }
3438
3440 void computePartials(const value_type& bar,
3441 value_type partials[]) const {
3442 if (min_v1)
3443 expr2.computePartials(value_type(0.0), partials);
3444 else
3445 expr2.computePartials(bar, partials);
3446 }
3447
3449 void getTangents(int i, value_type dots[]) const {
3450 expr2.getTangents(i, dots);
3451 }
3452
3453 template <int Arg>
3455 value_type getTangent(int i) const {
3456 return expr2.template getTangent<Arg>(i);
3457 }
3458
3460 bool isLinear() const {
3461 return false;
3462 }
3463
3465 bool hasFastAccess() const {
3466 return expr2.hasFastAccess();
3467 }
3468
3470 const value_type dx(int i) const {
3471 return min_v1 ? value_type(0.0) : expr2.dx(i);
3472 }
3473
3475 const value_type fastAccessDx(int i) const {
3476 return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3477 }
3478
3480 const value_type* getDx(int j) const {
3481 return expr2.getDx(j);
3482 }
3483
3484 protected:
3485
3486 ExprT1 expr1;
3487 const ExprT2& expr2;
3488 mutable value_type v;
3489 mutable bool min_v1;
3490
3491 };
3492
3493 }
3494
3495}
3496
3497#define FAD_BINARYOP_MACRO(OPNAME,OP) \
3498namespace Sacado { \
3499 namespace ELRCacheFad { \
3500 \
3501 template <typename T1, typename T2> \
3502 SACADO_INLINE_FUNCTION \
3503 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
3504 OPNAME (const T1& expr1, const T2& expr2) \
3505 { \
3506 typedef OP< T1, T2 > expr_t; \
3507 \
3508 return Expr<expr_t>(expr1, expr2); \
3509 } \
3510 \
3511 template <typename T> \
3512 SACADO_INLINE_FUNCTION \
3513 Expr< OP< Expr<T>, Expr<T> > > \
3514 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
3515 { \
3516 typedef OP< Expr<T>, Expr<T> > expr_t; \
3517 \
3518 return Expr<expr_t>(expr1, expr2); \
3519 } \
3520 \
3521 template <typename T> \
3522 SACADO_INLINE_FUNCTION \
3523 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
3524 Expr<T> > > \
3525 OPNAME (const typename Expr<T>::value_type& c, \
3526 const Expr<T>& expr) \
3527 { \
3528 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3529 typedef OP< ConstT, Expr<T> > expr_t; \
3530 \
3531 return Expr<expr_t>(ConstT(c), expr); \
3532 } \
3533 \
3534 template <typename T> \
3535 SACADO_INLINE_FUNCTION \
3536 Expr< OP< Expr<T>, \
3537 ConstExpr<typename Expr<T>::value_type> > > \
3538 OPNAME (const Expr<T>& expr, \
3539 const typename Expr<T>::value_type& c) \
3540 { \
3541 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3542 typedef OP< Expr<T>, ConstT > expr_t; \
3543 \
3544 return Expr<expr_t>(expr, ConstT(c)); \
3545 } \
3546 \
3547 template <typename T> \
3548 SACADO_INLINE_FUNCTION \
3549 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
3550 OPNAME (const typename Expr<T>::scalar_type& c, \
3551 const Expr<T>& expr) \
3552 { \
3553 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3554 typedef OP< ConstT, Expr<T> > expr_t; \
3555 \
3556 return Expr<expr_t>(ConstT(c), expr); \
3557 } \
3558 \
3559 template <typename T> \
3560 SACADO_INLINE_FUNCTION \
3561 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
3562 OPNAME (const Expr<T>& expr, \
3563 const typename Expr<T>::scalar_type& c) \
3564 { \
3565 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3566 typedef OP< Expr<T>, ConstT > expr_t; \
3567 \
3568 return Expr<expr_t>(expr, ConstT(c)); \
3569 } \
3570 } \
3571}
3572
3573
3582
3583#undef FAD_BINARYOP_MACRO
3584
3585//-------------------------- Relational Operators -----------------------
3586
3587#define FAD_RELOP_MACRO(OP) \
3588namespace Sacado { \
3589 namespace ELRCacheFad { \
3590 template <typename ExprT1, typename ExprT2> \
3591 SACADO_INLINE_FUNCTION \
3592 bool \
3593 operator OP (const Expr<ExprT1>& expr1, \
3594 const Expr<ExprT2>& expr2) \
3595 { \
3596 expr1.cache(); \
3597 expr2.cache(); \
3598 return expr1.val() OP expr2.val(); \
3599 } \
3600 \
3601 template <typename ExprT2> \
3602 SACADO_INLINE_FUNCTION \
3603 bool \
3604 operator OP (const typename Expr<ExprT2>::value_type& a, \
3605 const Expr<ExprT2>& expr2) \
3606 { \
3607 expr2.cache(); \
3608 return a OP expr2.val(); \
3609 } \
3610 \
3611 template <typename ExprT1> \
3612 SACADO_INLINE_FUNCTION \
3613 bool \
3614 operator OP (const Expr<ExprT1>& expr1, \
3615 const typename Expr<ExprT1>::value_type& b) \
3616 { \
3617 expr1.cache(); \
3618 return expr1.val() OP b; \
3619 } \
3620 } \
3621}
3622
3629FAD_RELOP_MACRO(<<=)
3630FAD_RELOP_MACRO(>>=)
3633
3634#undef FAD_RELOP_MACRO
3635
3636namespace Sacado {
3637
3638 namespace ELRCacheFad {
3639
3640 template <typename ExprT>
3642 bool operator ! (const Expr<ExprT>& expr)
3643 {
3644 expr.cache();
3645 return ! expr.val();
3646 }
3647
3648 } // namespace ELRCacheFad
3649
3650} // namespace Sacado
3651
3652//-------------------------- Boolean Operators -----------------------
3653namespace Sacado {
3654
3655 namespace ELRCacheFad {
3656
3657 template <typename ExprT>
3659 bool toBool(const Expr<ExprT>& x) {
3660 x.cache();
3661 bool is_zero = (x.val() == 0.0);
3662 for (int i=0; i<x.size(); i++)
3663 is_zero = is_zero && (x.dx(i) == 0.0);
3664 return !is_zero;
3665 }
3666
3667 } // namespace Fad
3668
3669} // namespace Sacado
3670
3671#define FAD_BOOL_MACRO(OP) \
3672namespace Sacado { \
3673 namespace ELRCacheFad { \
3674 template <typename ExprT1, typename ExprT2> \
3675 SACADO_INLINE_FUNCTION \
3676 bool \
3677 operator OP (const Expr<ExprT1>& expr1, \
3678 const Expr<ExprT2>& expr2) \
3679 { \
3680 return toBool(expr1) OP toBool(expr2); \
3681 } \
3682 \
3683 template <typename ExprT2> \
3684 SACADO_INLINE_FUNCTION \
3685 bool \
3686 operator OP (const typename Expr<ExprT2>::value_type& a, \
3687 const Expr<ExprT2>& expr2) \
3688 { \
3689 return a OP toBool(expr2); \
3690 } \
3691 \
3692 template <typename ExprT1> \
3693 SACADO_INLINE_FUNCTION \
3694 bool \
3695 operator OP (const Expr<ExprT1>& expr1, \
3696 const typename Expr<ExprT1>::value_type& b) \
3697 { \
3698 return toBool(expr1) OP b; \
3699 } \
3700 } \
3701}
3702
3705
3706#undef FAD_BOOL_MACRO
3707
3708//-------------------------- I/O Operators -----------------------
3709
3710namespace Sacado {
3711
3712 namespace ELRCacheFad {
3713
3714 template <typename ExprT>
3715 std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
3716 os << x.val() << " [";
3717
3718 for (int i=0; i< x.size(); i++) {
3719 os << " " << x.dx(i);
3720 }
3721
3722 os << " ]";
3723 return os;
3724 }
3725
3726 } // namespace Fad
3727
3728} // namespace Sacado
3729
3730#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)
fabs(expr.val())
abs(expr.val())
expr expr dx(i)
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 DivisionOp
expr expr expr ExpOp
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
expr val()
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 PowerOp
#define T1(r, f)
Definition: Sacado_rad.hpp:603
#define T2(r, f)
Definition: Sacado_rad.hpp:578
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 bool isActive() const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION bool isLinear() 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 isActive() const
SACADO_INLINE_FUNCTION bool isLinear() const
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 value_type val() 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.
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)
std::ostream & operator<<(std::ostream &os, const GeneralFad< T, Storage > &x)
SACADO_INLINE_FUNCTION Expr< UnaryPlusOp< Expr< T > > > operator+(const Expr< T > &expr)
float atanh(float x)
float asinh(float x)
float acosh(float x)
Base template specification for Promote.