Go to the documentation of this file.00001 #ifndef VIENNAMATH_RUNTIME_VECTOR_EXPR_HPP
00002 #define VIENNAMATH_RUNTIME_VECTOR_EXPR_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <ostream>
00019 #include <sstream>
00020 #include <memory>
00021 #include <assert.h>
00022 #include "viennamath/forwards.h"
00023 #include "viennamath/exception.hpp"
00024 #include "viennamath/runtime/expr.hpp"
00025
00026
00027
00032 namespace viennamath
00033 {
00034
00041 template <typename InterfaceType >
00042 class rt_vector_expr : public InterfaceType, public std::vector< viennamath::rt_expr<InterfaceType> >
00043 {
00044 typedef std::vector< viennamath::rt_expr<InterfaceType> > BaseType;
00045 typedef rt_vector_expr<InterfaceType> self_type;
00046
00047 public:
00048 typedef typename InterfaceType::numeric_type numeric_type;
00049 typedef InterfaceType interface_type;
00050 typedef typename BaseType::size_type size_type;
00051
00053 explicit rt_vector_expr(size_type num) : BaseType(num)
00054 {
00055
00056 for (std::size_t i=0; i<num; ++i)
00057 BaseType::operator[](i) = viennamath::rt_constant<numeric_type, interface_type>(0);
00058 }
00059
00061 self_type operator+(self_type const & other) const
00062 {
00063 assert(BaseType::size() == other.size() && "Expression vector dimensions mismatch");
00064
00065 self_type result(other.size());
00066 for (std::size_t i=0; i<other.size(); ++i)
00067 result[i] = (*this)[i] + other[i];
00068
00069 return result;
00070 }
00071
00073 self_type operator-(self_type const & other) const
00074 {
00075 assert(BaseType::size() == other.size() && "Expression vector dimensions mismatch");
00076
00077 self_type result(other.size());
00078 for (std::size_t i=0; i<other.size(); ++i)
00079 result[i] = (*this)[i] - other[i];
00080
00081 return result;
00082 }
00083
00084
00085
00086
00089 InterfaceType * clone() const
00090 {
00091 self_type * result = new self_type(BaseType::size());
00092
00093 for (std::size_t i=0; i<result->size(); ++i)
00094
00095 (*result)[i] = (*this)[i];
00096
00097 return result;
00098 }
00099
00101 std::string deep_str() const
00102 {
00103 std::stringstream ss;
00104 ss << *this;
00105 return ss.str();
00106 }
00107
00109 std::string shallow_str() const
00110 {
00111 return std::string("vector_expr");
00112 }
00113
00114
00117 numeric_type eval(std::vector<double> const & v) const
00118 {
00119 throw expression_not_evaluable_exception("Cannot evaluate a rt_vector_expr!");
00120 return 0;
00121 }
00122
00125 numeric_type eval(numeric_type val) const
00126 {
00127 throw expression_not_evaluable_exception("Cannot evaluate a rt_vector_expr!");
00128 return 0;
00129 }
00130
00133 numeric_type unwrap() const
00134 {
00135 throw expression_not_unwrappable_exception("Cannot unwrap a rt_vector_expr!");
00136 return 0;
00137 }
00138
00140 bool deep_equal(const InterfaceType * other) const
00141 {
00142 if (dynamic_cast< const self_type * >(other) != NULL)
00143 {
00144 const self_type * temp = dynamic_cast< const self_type * >(other);
00145 bool is_equal = true;
00146
00147 for (std::size_t i=0; i<temp->size(); ++i)
00148 is_equal = is_equal && (*this)[i].get()->deep_equal( (*temp)[i].get() );
00149
00150
00151 return is_equal;
00152 }
00153 return false;
00154 }
00155
00157 bool shallow_equal(const InterfaceType * other) const
00158 {
00159 return dynamic_cast< const self_type * >(other) != NULL;
00160 }
00161
00162
00164 InterfaceType * substitute(const InterfaceType * e,
00165 const InterfaceType * repl) const
00166 {
00167 if (deep_equal(e))
00168 return repl->clone();
00169
00170 self_type * result = new self_type(BaseType::size());
00171
00172 for (std::size_t i=0; i<result->size(); ++i)
00173 (*result)[i] = viennamath::rt_expr<InterfaceType>((*this)[i].get()->substitute(e, repl));
00174
00175 return result;
00176 };
00177
00179 InterfaceType * substitute(std::vector<const InterfaceType *> const & e,
00180 std::vector<const InterfaceType *> const & repl) const
00181 {
00182 for (std::size_t i=0; i<e.size(); ++i)
00183 if (deep_equal(e[i]))
00184 return repl[i]->clone();
00185
00186 self_type * result = new self_type(BaseType::size());
00187
00188 for (std::size_t i=0; i<result->size(); ++i)
00189 (*result)[i] = viennamath::rt_expr<InterfaceType>((*this)[i].get()->substitute(e, repl));
00190
00191 return result;
00192 };
00193
00195 InterfaceType * optimize() const
00196 {
00197 self_type * result = new self_type(BaseType::size());
00198
00199 for (std::size_t i=0; i<result->size(); ++i)
00200 (*result)[i] = viennamath::rt_expr<InterfaceType>((*this)[i].get()->optimize());
00201
00202 return result;
00203 }
00204
00206 bool optimizable() const
00207 {
00208 for (std::size_t i=0; i<BaseType::size(); ++i)
00209 if ( (*this)[i].get()->optimizable() == true )
00210 return true;
00211
00212 return false;
00213 }
00214
00216 InterfaceType * diff(const InterfaceType * diff_var) const
00217 {
00218 self_type * result = new self_type(BaseType::size());
00219
00220 for (std::size_t i=0; i<result->size(); ++i)
00221 (*result)[i] = viennamath::rt_expr<InterfaceType>((*this)[i].get()->diff(diff_var));
00222
00223 return result;
00224 }
00225
00226
00227 };
00228
00229
00230
00231
00232
00233 template <typename InterfaceType>
00234 std::ostream& operator<<(std::ostream & stream, rt_vector_expr<InterfaceType> const & e)
00235 {
00236 stream << "[" << e.size() << "](";
00237 for (std::size_t i=0; i<e.size(); ++i)
00238 {
00239 stream << e[i];
00240 if (i+1 < e.size())
00241 stream << ", ";
00242 }
00243 stream << ")";
00244
00245 return stream;
00246 }
00247
00248
00249 template <typename InterfaceType, typename T>
00250 rt_vector_expr<InterfaceType> operator*(rt_vector_expr<InterfaceType> const & lhs, T const & rhs)
00251 {
00252 rt_vector_expr<InterfaceType> result(lhs.size());
00253 for (std::size_t i=0; i<lhs.size(); ++i)
00254 result[i] = lhs[i] * rhs;
00255
00256 return result;
00257 }
00258
00259 template <typename T, typename InterfaceType>
00260 rt_vector_expr<InterfaceType> operator*(T const & lhs, rt_vector_expr<InterfaceType> const & rhs)
00261 {
00262 rt_vector_expr<InterfaceType> result(rhs.size());
00263 for (std::size_t i=0; i<rhs.size(); ++i)
00264 result[i] = lhs * rhs[i];
00265
00266 return result;
00267 }
00268
00269
00270 template <typename InterfaceType>
00271 rt_expr<InterfaceType> operator*(rt_vector_expr<InterfaceType> const & lhs, rt_vector_expr<InterfaceType> const & rhs)
00272 {
00273 assert(lhs.size() == rhs.size() && lhs.size() > 0 && "Invalid or nonmatching size in expression vectors");
00274
00275 rt_expr<InterfaceType> result = lhs[0] * rhs[0];
00276 for (std::size_t i=1; i<rhs.size(); ++i)
00277 result = result + lhs[i] * rhs[i];
00278
00279 return result;
00280 }
00281
00282
00283
00284 template <typename InterfaceType, typename T>
00285 rt_vector_expr<InterfaceType> operator/(rt_vector_expr<InterfaceType> const & lhs, T const & rhs)
00286 {
00287 rt_vector_expr<InterfaceType> result(lhs.size());
00288 for (std::size_t i=0; i<lhs.size(); ++i)
00289 result[i] = lhs[i] / rhs;
00290
00291 return result;
00292 }
00293
00294 template <typename T, typename InterfaceType>
00295 rt_vector_expr<InterfaceType> operator/(T const & lhs, rt_vector_expr<InterfaceType> const & rhs)
00296 {
00297 rt_vector_expr<InterfaceType> result(rhs.size());
00298 for (std::size_t i=0; i<rhs.size(); ++i)
00299 result[i] = lhs / rhs[i];
00300
00301 return result;
00302 }
00303
00304
00305
00306
00307
00308
00309 }
00310
00311 #endif