00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #ifndef SACADO_ELRFAD_EXPRESSION_HPP
00055 #define SACADO_ELRFAD_EXPRESSION_HPP
00056
00057 #include "Sacado_Traits.hpp"
00058
00059 namespace Sacado {
00060
00061 namespace ELRFad {
00062
00064
00068 template <typename A, typename B> struct ExprPromote {};
00069
00071 template <typename A> struct ExprPromote<A,A> {
00072 typedef A type;
00073 };
00074
00076
00080 template <typename ExprT>
00081 class Expr {
00082
00083 public:
00084
00086 typedef typename ExprT::value_type value_type;
00087
00089 typedef typename ExprT::base_expr_type base_expr_type;
00090
00092 static const int num_args = ExprT::num_args;
00093
00095 explicit Expr(const ExprT& expr) : expr_(expr) {}
00096
00098 int size() const {return expr_.size();}
00099
00101 value_type val() const { return expr_.val();}
00102
00104 void computePartials(const value_type& bar,
00105 value_type partials[]) const {
00106 expr_.computePartials(bar, partials); }
00107
00109 void getTangents(int i, value_type dots[]) const {
00110 expr_.getTangents(i, dots); }
00111
00113 template <int Arg>
00114 value_type getTangent(int i) const {
00115 return expr_.template getTangent<Arg>(i);
00116 }
00117
00119 template <int Arg>
00120 bool isActive() const { return expr_.template isActive<Arg>(); }
00121
00122 protected:
00123
00125 Expr() {}
00126
00128 ExprT expr_;
00129
00130 };
00131
00133
00136 template <typename ConstT>
00137 class ConstExpr {
00138
00139 public:
00140
00142 typedef ConstT value_type;
00143
00145 typedef ConstT base_expr_type;
00146
00148 static const int num_args = 0;
00149
00151 ConstExpr(const ConstT& constant) : constant_(constant) {}
00152
00154 int size() const { return 0; }
00155
00157 value_type val() const { return constant_; }
00158
00160 void computePartials(const value_type& bar,
00161 value_type partials[]) const {}
00162
00164 void getTangents(int i, value_type dots[]) const {}
00165
00167 template <int Arg>
00168 value_type getTangent(int i) const { return 0.0; }
00169
00171 template <int Arg>
00172 bool isActive() const { return false; }
00173
00174 protected:
00175
00177 const ConstT& constant_;
00178
00179 };
00180
00182
00188 template <typename ExprT, template<typename> class Op>
00189 class UnaryExpr {
00190
00191 public:
00192
00194 typedef typename ExprT::value_type value_type;
00195
00197 typedef typename ExprT::base_expr_type base_expr_type;
00198
00200 typedef Op<ExprT> OpT;
00201
00203 static const int num_args = ExprT::num_args;
00204
00206 UnaryExpr(const ExprT& expr) : expr_(expr) {}
00207
00209 int size() const { return expr_.size(); }
00210
00212 value_type val() const { return OpT::computeValue(expr_); }
00213
00215 void computePartials(const value_type& bar,
00216 value_type partials[]) const {
00217 expr_.computePartials(OpT::computeAdjoint(bar, expr_), partials); }
00218
00220 void getTangents(int i, value_type dots[]) const {
00221 expr_.getTangents(i, dots); }
00222
00224 template <int Arg>
00225 value_type getTangent(int i) const {
00226 return expr_.template getTangent<Arg>(i);
00227 }
00228
00230 template <int Arg>
00231 bool isActive() const { return expr_.template isActive<Arg>(); }
00232
00233 protected:
00234
00236 const ExprT& expr_;
00237
00238 };
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 template <typename T> struct ExprConstRef {
00249 typedef const T& type;
00250 };
00251 template <typename T> struct ExprConstRef< ConstExpr<T> > {
00252 typedef const ConstExpr<T> type;
00253 };
00254
00256
00263 template <typename ExprT1, typename ExprT2,
00264 template<typename,typename> class Op>
00265 class BinaryExpr {
00266
00267 public:
00268
00270 typedef typename ExprT1::value_type value_type_1;
00271
00273 typedef typename ExprT2::value_type value_type_2;
00274
00276 typedef typename Sacado::Promote<value_type_1,
00277 value_type_2>::type value_type;
00278
00280 typedef typename ExprT1::base_expr_type base_expr_type_1;
00281
00283 typedef typename ExprT2::base_expr_type base_expr_type_2;
00284
00286 typedef typename ExprPromote<base_expr_type_1,
00287 base_expr_type_2>::type base_expr_type;
00288
00290 static const int num_args1 = ExprT1::num_args;
00291
00293 static const int num_args2 = ExprT2::num_args;
00294
00296 static const int num_args = num_args1 + num_args2;
00297
00298 typedef Op<ExprT1,ExprT2> OpT;
00299
00301 BinaryExpr(const ExprT1& expr1, const ExprT2& expr2) :
00302 expr1_(expr1), expr2_(expr2) {}
00303
00305 int size() const {
00306 int sz1 = expr1_.size(), sz2 = expr2_.size();
00307 return sz1 > sz2 ? sz1 : sz2;
00308 }
00309
00311 void computePartials(const value_type& bar,
00312 value_type partials[]) const {
00313 if (num_args1 > 0)
00314 expr1_.computePartials(OpT::computeLeftAdjoint(bar, expr1_, expr2_),
00315 partials);
00316 if (num_args2 > 0)
00317 expr2_.computePartials(OpT::computeRightAdjoint(bar, expr1_, expr2_),
00318 partials+num_args1);
00319 }
00320
00322 void getTangents(int i, value_type dots[]) const {
00323 expr1_.getTangents(i, dots);
00324 expr2_.getTangents(i, dots+num_args1); }
00325
00327 value_type val() const {
00328 return OpT::computeValue(expr1_,expr2_); }
00329
00331 template <int Arg>
00332 value_type getTangent(int i) const {
00333 if (Arg < num_args1)
00334 return expr1_.template getTangent<Arg>(i);
00335 else
00336 return expr2_.template getTangent<Arg-num_args1>(i);
00337 }
00338
00340 template <int Arg>
00341 bool isActive() const {
00342 if (Arg < num_args1)
00343 return expr1_.template isActive<Arg>();
00344 else
00345 return expr2_.template isActive<Arg-num_args1>();
00346 }
00347
00348 protected:
00349
00351 typename ExprConstRef<ExprT1>::type expr1_;
00352
00354 typename ExprConstRef<ExprT2>::type expr2_;
00355
00356 };
00357
00358 }
00359
00360 }
00361
00362 #endif // SACADO_ELRFAD_EXPRESSION_HPP