Go to the documentation of this file.00001 #ifndef VIENNAMATH_RUNTIME_UNARY_EXPRESSION_HPP
00002 #define VIENNAMATH_RUNTIME_UNARY_EXPRESSION_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021 #include <ostream>
00022 #include <sstream>
00023 #include <memory>
00024 #include "viennamath/forwards.h"
00025 #include "viennamath/compiletime/unary_op_tags.hpp"
00026 #include "viennamath/compiletime/ct_unary_expr.hpp"
00027 #include "viennamath/runtime/constant.hpp"
00028 #include "viennamath/runtime/op_interface.hpp"
00029 #include "viennamath/runtime/expression_interface.hpp"
00030
00035 namespace viennamath
00036 {
00037
00038
00043 template <typename InterfaceType >
00044 class rt_unary_expr : public InterfaceType
00045 {
00046 typedef op_interface<InterfaceType> op_interface_type;
00047 typedef op_unary<op_id<typename InterfaceType::numeric_type>, InterfaceType> op_unary_id_type;
00048
00049 typedef rt_unary_expr<InterfaceType> self_type;
00050
00051 public:
00052 typedef typename InterfaceType::numeric_type numeric_type;
00053
00054 rt_unary_expr() {}
00055
00056 explicit rt_unary_expr(InterfaceType * lhs,
00057 op_interface_type * op) : expr_(lhs),
00058 op_(op) {}
00059
00060 explicit rt_unary_expr(InterfaceType * lhs) : expr_(lhs),
00061 op_(new op_unary_id_type()) {}
00062
00063 template <typename LHS, typename OP, typename RHS>
00064 explicit rt_unary_expr(ct_unary_expr<LHS, OP> const & other) : op_(new OP())
00065 {
00066
00067 expr_ = std::auto_ptr<InterfaceType>(other.lhs().clone());
00068 }
00069
00070 explicit rt_unary_expr(rt_variable<InterfaceType> const & other) : expr_(other.clone()),
00071 op_(new op_unary_id_type()) {}
00072
00073 template <typename T>
00074 explicit rt_unary_expr(rt_constant<T, InterfaceType> const & other) : expr_(other.clone()),
00075 op_(new op_unary_id_type()) {}
00076
00077 template <long value>
00078 explicit rt_unary_expr(ct_constant<value> const & other) : expr_(other.clone()),
00079 op_(new op_unary_id_type()) {}
00080
00081
00082 rt_unary_expr(rt_unary_expr const & other) : expr_(other.expr_->clone()),
00083 op_(other.op_->clone()) {};
00084
00085
00086 template <typename LHS, typename OP>
00087 rt_unary_expr & operator=(ct_unary_expr<LHS, OP> const & other)
00088 {
00089 expr_ = std::auto_ptr<InterfaceType>(other.lhs().clone());
00090 op_ = std::auto_ptr<op_interface_type>(new OP());
00091 return *this;
00092 }
00093
00094 rt_unary_expr & operator=(rt_unary_expr const & other)
00095 {
00096 expr_ = std::auto_ptr<InterfaceType>(other.lhs_->clone());
00097 op_ = std::auto_ptr<op_interface_type>(other.op_->clone());
00098 return *this;
00099 }
00100
00101 template <typename ScalarType>
00102 rt_unary_expr & operator=(rt_constant<ScalarType> const & other)
00103 {
00104 expr_ = std::auto_ptr<InterfaceType>(other.clone());
00105 op_ = std::auto_ptr<op_interface_type>(new op_unary_id_type());
00106 return *this;
00107 }
00108
00109 template <long value>
00110 rt_unary_expr & operator=(ct_constant<value> const & other)
00111 {
00112 return *this = value;
00113 }
00114
00115 rt_unary_expr & operator=(numeric_type value)
00116 {
00117 expr_ = std::auto_ptr<InterfaceType>(new rt_constant<numeric_type>(value));
00118 op_ = std::auto_ptr<op_interface_type>(new op_unary_id_type());
00119 return *this;
00120 }
00121
00123 const InterfaceType * lhs() const { return expr_.get(); }
00124
00126 const op_interface_type * op() const { return op_.get(); }
00127
00129
00130
00132 numeric_type operator()(numeric_type val) const
00133 {
00134 return this->eval(val);
00135 }
00136
00138 template <typename ScalarType>
00139 numeric_type operator()(rt_constant<ScalarType> val) const
00140 {
00141 return this->eval(static_cast<numeric_type>(val));
00142 }
00143
00145 template <long value>
00146 numeric_type operator()(ct_constant<value> val) const
00147 {
00148 return this->eval(value);
00149 }
00150
00152 template <typename VectorType>
00153 numeric_type operator()(VectorType const & v) const
00154 {
00155 std::vector<double> stl_v(v.size());
00156 for (std::size_t i=0; i<v.size(); ++i)
00157 stl_v[i] = v[i];
00158
00159 return this->eval(stl_v);
00160 }
00161
00163 numeric_type operator()(std::vector<numeric_type> const & stl_v) const
00164 {
00165 return this->eval(stl_v);
00166 }
00167
00169 template <typename T0>
00170 numeric_type operator()(viennamath::ct_vector_1<T0> const & v) const
00171 {
00172 std::vector<double> stl_v(1);
00173 stl_v[0] = v[ct_index<0>()];
00174 return this->eval(stl_v);
00175 }
00176
00178 template <typename T0, typename T1>
00179 numeric_type operator()(viennamath::ct_vector_2<T0, T1> const & v) const
00180 {
00181 std::vector<double> stl_v(2);
00182 stl_v[0] = v[ct_index<0>()];
00183 stl_v[1] = v[ct_index<1>()];
00184 return this->eval(stl_v);
00185 }
00186
00188 template <typename T0, typename T1, typename T2>
00189 numeric_type operator()(viennamath::ct_vector_3<T0, T1, T2> const & v) const
00190 {
00191 std::vector<double> stl_v(3);
00192 stl_v[0] = v[ct_index<0>()];
00193 stl_v[1] = v[ct_index<1>()];
00194 stl_v[2] = v[ct_index<2>()];
00195 return this->eval(stl_v);
00196 }
00197
00198
00200 numeric_type eval(std::vector<double> const & v) const
00201 {
00202 return op_->apply(expr_.get()->eval(v));
00203 }
00204
00206 numeric_type eval(numeric_type val) const
00207 {
00208 return op_->apply(expr_.get()->eval(val));
00209 }
00210
00212
00214 InterfaceType * simplify() const
00215 {
00216 if (expr_->is_constant())
00217 {
00218 if (op_->can_simplify())
00219 return new rt_constant<numeric_type, InterfaceType>( op_->apply(expr_->unwrap()) );
00220 else
00221 return new rt_unary_expr(new rt_constant<numeric_type, InterfaceType>(expr_->unwrap()),
00222 op_->clone());
00223 }
00224
00225
00226
00227 return new rt_unary_expr(expr_->simplify(), op_->clone());
00228 }
00229
00231 bool can_simplify() const
00232 {
00233 if (expr_->can_simplify())
00234 {
00235
00236 return true;
00237 }
00238 return false;
00239 }
00240
00241
00243
00244 InterfaceType * clone() const { return new rt_unary_expr(expr_->clone(), op_->clone()); }
00245
00247 std::string deep_str() const
00248 {
00249 std::stringstream ss;
00250 ss << op_->str();
00251 ss << "(";
00252 ss << expr_->deep_str();
00253 ss << ")";
00254 return ss.str();
00255 }
00256
00258 std::string shallow_str() const
00259 {
00260 return std::string("unary_expr");
00261 }
00262
00264 numeric_type unwrap() const
00265 {
00266
00267
00268 return op_->apply(expr_->unwrap());
00269 }
00270
00272 InterfaceType * substitute(const InterfaceType * e,
00273 const InterfaceType * repl) const
00274 {
00275 if (deep_equal(e))
00276 return repl->clone();
00277
00278 return new rt_unary_expr(expr_->substitute(e, repl),
00279 op_->clone());
00280 };
00281
00283 InterfaceType * substitute(std::vector<const InterfaceType *> const & e,
00284 std::vector<const InterfaceType *> const & repl) const
00285 {
00286 for (std::size_t i=0; i<e.size(); ++i)
00287 if (deep_equal(e[i]))
00288 return repl[i]->clone();
00289
00290 return new rt_unary_expr(expr_->substitute(e, repl),
00291 op_->clone());
00292 };
00293
00295 bool deep_equal(const InterfaceType * other) const
00296 {
00297 if (dynamic_cast<const rt_unary_expr *>(other) != NULL)
00298 {
00299 const rt_unary_expr * temp = dynamic_cast<const rt_unary_expr *>(other);
00300
00301 return expr_->deep_equal(temp->expr_.get())
00302 && op_->equal(temp->op_.get());
00303 }
00304 return false;
00305 }
00306
00308 bool shallow_equal(const InterfaceType * other) const
00309 {
00310 return dynamic_cast< const self_type * >(other) != NULL;
00311 }
00312
00314 InterfaceType * diff(const InterfaceType * diff_var) const
00315 {
00316 return op_->diff(expr_.get(), diff_var);
00317 }
00318
00320 InterfaceType * recursive_manipulation(rt_manipulation_wrapper<InterfaceType> const & fw) const
00321 {
00322 if (fw.modifies(this))
00323 return fw(this);
00324
00325 return new rt_unary_expr(expr_->recursive_manipulation(fw),
00326 op_->clone() );
00327 }
00328
00330 void recursive_traversal(rt_traversal_wrapper<InterfaceType> const & fw) const
00331 {
00332 fw(this);
00333 expr_->recursive_traversal(fw);
00334 }
00335
00336 private:
00337 std::auto_ptr<InterfaceType> expr_;
00338 std::auto_ptr<op_interface_type> op_;
00339 };
00340
00342 template <typename InterfaceType>
00343 std::ostream& operator<<(std::ostream & stream, rt_unary_expr<InterfaceType> const & e)
00344 {
00345 stream << "unary"
00346 << e.deep_str()
00347 << "";
00348 return stream;
00349 }
00350
00351
00352 }
00353
00354 #endif