00001 #ifndef VIENNAMATH_MANIPULATION_SUBSTITUTE_HPP
00002 #define VIENNAMATH_MANIPULATION_SUBSTITUTE_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00033
00034
00035 namespace result_of
00036 {
00038 template <typename SearchType,
00039 typename ReplacementType,
00040 typename ExpressionType>
00041 struct substitute {};
00042
00043
00044
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
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
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
00159
00160
00161
00162
00163
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
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
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
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
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
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 }
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