• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List

/export/development/ViennaMath/viennamath/runtime/vector_expr.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_RUNTIME_VECTOR_EXPR_HPP
00002 #define VIENNAMATH_RUNTIME_VECTOR_EXPR_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2012, Institute for Microelectronics,
00006                        Institute for Analysis and Scientific Computing,
00007                        TU Wien.
00008                              -----------------
00009                ViennaMath - Symbolic and Numerical Math in C++
00010                              -----------------
00011 
00012    Author:     Karl Rupp                          rupp@iue.tuwien.ac.at
00013 
00014    License:    MIT (X11), see file LICENSE in the ViennaMath base directory
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 /* see forwards.h for default argument */>
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         //initialize all zeros:
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       // Interface requirements:
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           //(*result)[i] = viennamath::rt_expr<InterfaceType>((*this)[i].get()->clone());
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       //virtual functions for evaluations
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   // Operator overloads
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   //operator*
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   //special case: dot product:
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   // operator/
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   // Other functionality (inner_prod, etc.)
00307   //
00308   
00309 }
00310 
00311 #endif

Generated on Wed Feb 29 2012 21:50:43 for ViennaMath by  doxygen 1.7.1