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

/export/development/ViennaMath/viennamath/manipulation/substitute.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_MANIPULATION_SUBSTITUTE_HPP
00002 #define VIENNAMATH_MANIPULATION_SUBSTITUTE_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 
00019 #include "viennamath/forwards.h"
00020 #include "viennamath/runtime/functor_wrapper.hpp"
00021 #include "viennamath/manipulation/simplify.hpp"
00022 #include <assert.h>
00023 
00028 namespace viennamath
00029 {
00030   
00031   //
00032   //   Section 1: Compile time substitution
00033   //
00034   
00035   namespace result_of
00036   {
00038     template <typename SearchType,
00039               typename ReplacementType,
00040               typename ExpressionType>
00041     struct substitute {};  //Note: not having a default type defined serves as SFINAE for viennamath::substitute() as well (no runtime types allowed)
00042     
00043     //
00044     // generic handling of primitives
00045     //
00047     template <typename SearchType,
00048               typename ReplacementType,
00049               typename LHS, typename OP, typename RHS>
00050     struct substitute <SearchType, ReplacementType, ct_binary_expr<LHS, OP, RHS> >
00051     {
00052       typedef ct_binary_expr< typename substitute<SearchType, ReplacementType, LHS>::type,
00053                               OP,
00054                               typename substitute<SearchType, ReplacementType, RHS>::type >   type;
00055     };
00056 
00058     template <typename SearchType,
00059               typename ReplacementType,
00060               typename LHS, typename OP>
00061     struct substitute <SearchType, ReplacementType, ct_unary_expr<LHS, OP> >
00062     {
00063       typedef ct_unary_expr< typename substitute<SearchType, ReplacementType, LHS>::type,
00064                              OP >   type;
00065     };
00066 
00068     template <typename SearchType,
00069               typename ReplacementType,
00070               long value>
00071     struct substitute <SearchType, ReplacementType, ct_constant<value> >
00072     {
00073       typedef ct_constant<value>   type;
00074     };
00075     
00077     template <typename SearchType,
00078               typename ReplacementType,
00079               typename TAG>
00080     struct substitute <SearchType, ReplacementType, ct_function_symbol<TAG> >
00081     {
00082       typedef ct_function_symbol<TAG>   type;
00083     };
00084     
00086     template <typename SearchType,
00087               typename ReplacementType,
00088               id_type id>
00089     struct substitute <SearchType, ReplacementType, ct_variable<id> >
00090     {
00091       typedef ct_variable<id>   type;
00092     };
00093     
00094     //
00095     // replacement specializations
00096     //
00098     template <typename ReplacementType,
00099               typename LHS, typename OP, typename RHS>
00100     struct substitute <ct_binary_expr<LHS, OP, RHS>, ReplacementType, ct_binary_expr<LHS, OP, RHS> >
00101     {
00102       typedef ReplacementType   type;
00103     };
00104 
00106     template <typename ReplacementType,
00107               typename LHS, typename OP>
00108     struct substitute <ct_unary_expr<LHS, OP>, ReplacementType, ct_unary_expr<LHS, OP> >
00109     {
00110       typedef ReplacementType   type;
00111     };
00112 
00114     template <typename ReplacementType,
00115               long value>
00116     struct substitute <ct_constant<value>, ReplacementType, ct_constant<value> >
00117     {
00118       typedef ReplacementType   type;
00119     };
00120     
00122     template <typename ReplacementType,
00123               typename TAG>
00124     struct substitute <ct_function_symbol<TAG>, ReplacementType, ct_function_symbol<TAG> >
00125     {
00126       typedef ReplacementType   type;
00127     };
00128     
00130     template <typename ReplacementType,
00131               id_type id>
00132     struct substitute <ct_variable<id>, ReplacementType, ct_variable<id> >
00133     {
00134       typedef ReplacementType   type;
00135     };
00136     
00137   }
00138   
00139   // interface:
00146   template <typename SearchType,
00147             typename ReplacementType,
00148             typename ExpressionType>
00149   typename result_of::substitute< SearchType, ReplacementType, ExpressionType>::type
00150   substitute(SearchType const &, ReplacementType const &, ExpressionType const & ex)
00151   {
00152     return typename result_of::substitute< SearchType, ReplacementType, ExpressionType>::type();
00153   }
00154   
00155   
00156   
00157   //
00158   //   Section 2: Run time substitution
00159   //
00160   
00161   
00162   
00163   //public interface:
00165   template <typename InterfaceType, typename ReplacementType, typename ExpressionType>
00166   rt_expr<InterfaceType> substitute(rt_variable<InterfaceType> const & u,
00167                                     ReplacementType const & repl,
00168                                     ExpressionType const & e)
00169   {
00170     rt_expr<InterfaceType> temp(e.substitute(&u, &repl));
00171     inplace_simplify(temp);
00172     return temp;
00173   }
00174 
00176   template <typename InterfaceType, typename ReplacementType>
00177   rt_expr<InterfaceType> substitute(rt_variable<InterfaceType> const & u,
00178                                     ReplacementType const & repl,
00179                                     rt_expr<InterfaceType> const & e)
00180   {
00181     rt_expr<InterfaceType> temp(e.get()->substitute(&u, &repl));
00182     inplace_simplify(temp);
00183     return temp;
00184   }
00185 
00187   template <typename InterfaceType>
00188   rt_expr<InterfaceType> substitute(rt_variable<InterfaceType> const & u,
00189                                     default_numeric_type repl,
00190                                     rt_expr<InterfaceType> const & e)
00191   {
00192     rt_constant<default_numeric_type, InterfaceType> c(repl);
00193     rt_expr<InterfaceType> temp(e.get()->substitute(&u, &c));
00194     inplace_simplify(temp);
00195     return temp;
00196   }
00197 
00199   template <typename InterfaceType>
00200   rt_expr<InterfaceType> substitute(rt_function_symbol<InterfaceType> const & u,
00201                                     default_numeric_type repl,
00202                                     rt_expr<InterfaceType> const & e)
00203   {
00204     rt_constant<default_numeric_type, InterfaceType> c(repl);
00205     rt_expr<InterfaceType> temp(e.get()->substitute(&u, &c));
00206     inplace_simplify(temp);
00207     return temp;
00208   }
00209 
00211   template <typename InterfaceType>
00212   rt_expr<InterfaceType> substitute(rt_function_symbol<InterfaceType> const & u,
00213                                     rt_expr<InterfaceType> const & repl,
00214                                     rt_expr<InterfaceType> const & e)
00215   {
00216     rt_expr<InterfaceType> temp(e.get()->substitute(&u, repl.get()));
00217     inplace_simplify(temp);
00218     return temp;
00219   }
00220 
00221   //substitute unary and  binary expressions:
00223   template <typename InterfaceType, typename ReplacementType>
00224   rt_expr<InterfaceType> substitute(rt_unary_expr<InterfaceType> const & search,
00225                                     ReplacementType const & repl,
00226                                     rt_expr<InterfaceType> const & e)
00227   {
00228     rt_expr<InterfaceType> temp(e.get()->substitute(&search, &repl));
00229     inplace_simplify(temp);
00230     return temp;
00231   }
00232 
00234   template <typename InterfaceType>
00235   rt_expr<InterfaceType> substitute(rt_unary_expr<InterfaceType> const & search,
00236                                     rt_expr<InterfaceType> const & repl,
00237                                     rt_expr<InterfaceType> const & e)
00238   {
00239     rt_expr<InterfaceType> temp(e.get()->substitute(&search, repl.get()));
00240     inplace_simplify(temp);
00241     return temp;
00242   }
00243 
00245   template <typename InterfaceType, typename ReplacementType>
00246   rt_expr<InterfaceType> substitute(rt_binary_expr<InterfaceType> const & search,
00247                                     ReplacementType const & repl,
00248                                     rt_expr<InterfaceType> const & e)
00249   {
00250     rt_expr<InterfaceType> temp(e.get()->substitute(&search, &repl));
00251     inplace_simplify(temp);
00252     return temp;
00253   }
00254 
00256   template <typename InterfaceType>
00257   rt_expr<InterfaceType> substitute(rt_expr<InterfaceType> const & search,
00258                                     rt_expr<InterfaceType> const & repl,
00259                                     rt_expr<InterfaceType> const & e)
00260   {
00261     rt_expr<InterfaceType> temp(e.get()->substitute(search.get(), repl.get()));
00262     inplace_simplify(temp);
00263     return temp;
00264   }
00265 
00266 
00268   template <typename InterfaceType>
00269   rt_expr<InterfaceType> substitute(std::vector<rt_expr<InterfaceType> > const & search,
00270                                     std::vector<rt_expr<InterfaceType> > const & repl,
00271                                     rt_expr<InterfaceType> const & e)
00272   {
00273     assert(search.size() == repl.size() && "Search and replace array must have the same length!");
00274     
00275     std::vector<const InterfaceType *> search_ptrs(search.size());
00276     for (size_t i=0; i<search_ptrs.size(); ++i)
00277       search_ptrs[i] = search[i].get();
00278     
00279     std::vector<const InterfaceType *> repl_ptrs(repl.size());
00280     for (size_t i=0; i<repl_ptrs.size(); ++i)
00281       repl_ptrs[i] = repl[i].get();
00282     
00283     rt_expr<InterfaceType> temp(e.get()->substitute(search_ptrs, repl_ptrs));
00284     inplace_simplify(temp);
00285     return temp;
00286   }
00287 
00288 
00289 
00290   // substitute intervals
00291   
00293   namespace detail
00294   {
00295     template <typename InterfaceType>
00296     class integral_substitution_functor : public viennamath::rt_manipulation_interface<InterfaceType>
00297     {
00298       public: 
00299         integral_substitution_functor(op_unary<op_rt_integral<InterfaceType>, InterfaceType> const * ptr) : ptr_(ptr) {}
00300         
00301         
00302         InterfaceType * operator()(InterfaceType const * e) const 
00303         {
00304           viennamath::rt_unary_expr<InterfaceType> const * ex_ptr = dynamic_cast< viennamath::rt_unary_expr<InterfaceType> const * >(e);
00305           if (ex_ptr != NULL)
00306           {
00307             typedef op_unary<op_rt_symbolic_integral<InterfaceType>, InterfaceType> const *  OpPtrType;
00308             
00309             OpPtrType op_ptr = dynamic_cast< OpPtrType >(ex_ptr->op());
00310             if (op_ptr != NULL)
00311             {
00312               //std::cout << "Modifies!" << std::endl;
00313               return new viennamath::rt_unary_expr<InterfaceType>(ex_ptr->lhs()->clone(), ptr_->clone());
00314             }
00315           }
00316           
00317           return e->clone();
00318         }
00319 
00320 
00321         bool modifies(InterfaceType const * e) const 
00322         {
00323           //std::cout << "Checking " << e->shallow_str() << std::endl;
00324           viennamath::rt_unary_expr<InterfaceType> const * ex_ptr = dynamic_cast< viennamath::rt_unary_expr<InterfaceType> const * >(e);
00325           if (ex_ptr != NULL)
00326           {
00327             typedef op_unary<op_rt_symbolic_integral<InterfaceType>, InterfaceType> const *  OpPtrType;
00328             
00329             OpPtrType op_ptr = dynamic_cast< OpPtrType >(ex_ptr->op());
00330             if (op_ptr != NULL)
00331             {
00332               //std::cout << "FOUND!" << std::endl;
00333               return true;
00334             }
00335           }
00336           return false;
00337         }
00338 
00339       private:
00340         std::auto_ptr<const op_unary<op_rt_integral<InterfaceType>, InterfaceType> > ptr_;
00341     };
00342   } //namespace detail
00343   
00350   template <typename InterfaceType, typename PairType>
00351   rt_expr<InterfaceType> substitute(rt_symbolic_interval<InterfaceType> const & search,
00352                                     PairType const & repl,
00353                                     rt_expr<InterfaceType> const & e)
00354   {
00355     typedef op_rt_integral<InterfaceType>    OperatorT;
00356     
00357     viennamath::rt_manipulation_wrapper<> fun( new detail::integral_substitution_functor<InterfaceType>(new op_unary<OperatorT>(OperatorT(repl.first, repl.second))) );
00358     
00359     rt_expr<InterfaceType> temp(e.get()->recursive_manipulation(fun));
00360     
00361     return temp;
00362   }
00363   
00364 }
00365 
00366 #endif

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