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

/export/development/ViennaMath/viennamath/manipulation/detail/binary_operations.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_BINARY_OPERATORS_MANIPULATION_HPP
00002 #define VIENNAMATH_BINARY_OPERATORS_MANIPULATION_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 
00020 #include <string>
00021 #include <vector>
00022 #include <math.h>
00023 #include "viennamath/forwards.h"
00024 #include "viennamath/compiletime/binary_op_tags.hpp"
00025 #include "viennamath/runtime/binary_expr.hpp"
00026 #include "viennamath/runtime/unary_expr.hpp"
00027 
00032 namespace viennamath
00033 {
00034 
00035   
00036   //
00037   // addition
00038   //
00040   template <typename InterfaceType, typename NumericT>
00041   InterfaceType * diff_impl(const InterfaceType * lhs, op_plus<NumericT>, const InterfaceType * rhs, const InterfaceType * diff_var)
00042   {
00043       return new rt_binary_expr<InterfaceType>( lhs->diff(diff_var),
00044                                                 new op_binary<op_plus<NumericT>, InterfaceType>(),
00045                                                 rhs->diff(diff_var) );
00046   }
00047   
00049   template <typename InterfaceType, typename NumericT>
00050   InterfaceType * simplify_impl(const InterfaceType * lhs, op_plus<NumericT>, const InterfaceType * rhs)
00051   {
00052         if (lhs->is_constant())
00053         {
00054           NumericT val = lhs->unwrap();
00055           if (val == 0.0)
00056             return rhs->simplify();
00057           
00058           return new rt_binary_expr<InterfaceType>(new rt_constant<NumericT, InterfaceType>(val),
00059                                                    new op_binary<op_plus<NumericT>, InterfaceType>(),
00060                                                    rhs->simplify());
00061         }
00062         else if (rhs->is_constant())
00063         {
00064           NumericT val = rhs->unwrap();
00065           if (val == 0.0)
00066             return lhs->simplify();
00067           
00068           return new rt_binary_expr<InterfaceType>(lhs->simplify(),
00069                                                    new op_binary<op_plus<NumericT>, InterfaceType>(),
00070                                                    new rt_constant<NumericT, InterfaceType>(val));
00071         }
00072         
00073         return new rt_binary_expr<InterfaceType>(lhs->simplify(),
00074                                                  new op_binary<op_plus<NumericT>, InterfaceType>(),
00075                                                  rhs->simplify());
00076   }
00077   
00079   template <typename InterfaceType, typename NumericT>
00080   bool can_simplify_impl(const InterfaceType * lhs, op_plus<NumericT>, const InterfaceType * rhs)
00081   {
00082       if (lhs->is_constant())
00083       {
00084         if (lhs->unwrap() == 0.0)
00085         {
00086           //std::cout << "can_simplify: true in op_plus" << std::endl;
00087           return true;
00088         }
00089       }
00090       if (rhs->is_constant())
00091       {
00092         if (rhs->unwrap() == 0.0)
00093         {
00094           //std::cout << "can_simplify: true in op_plus" << std::endl;
00095           return true;
00096         }
00097       }
00098       return lhs->can_simplify() || rhs->can_simplify();
00099   }
00100   
00101   
00102   
00103   
00104   //
00105   // subtraction
00106   //
00108   template <typename InterfaceType, typename NumericT>
00109   InterfaceType * diff_impl(const InterfaceType * lhs, op_minus<NumericT>, const InterfaceType * rhs, const InterfaceType * diff_var)
00110   {
00111       return new rt_binary_expr<InterfaceType>( lhs->diff(diff_var),
00112                                                 new op_binary<op_minus<NumericT>, InterfaceType>(),
00113                                                 rhs->diff(diff_var) );
00114   }
00115   
00117   template <typename InterfaceType, typename NumericT>
00118   InterfaceType * simplify_impl(const InterfaceType * lhs, op_minus<NumericT>, const InterfaceType * rhs)
00119   {
00120         if (lhs->is_constant())
00121         {
00122           NumericT val = lhs->unwrap();
00123           if (val == 0.0)
00124           {
00125             return new rt_binary_expr<InterfaceType>(new rt_constant<NumericT, InterfaceType>(-1),
00126                                                      new op_binary<op_mult<NumericT>, InterfaceType>(),
00127                                                      rhs->simplify());
00128           }
00129           
00130           return new rt_binary_expr<InterfaceType>(new rt_constant<NumericT, InterfaceType>(val),
00131                                                    new op_binary<op_minus<NumericT>, InterfaceType>(),
00132                                                    rhs->simplify());
00133         }
00134         else if (rhs->is_constant())
00135         {
00136           NumericT val = rhs->unwrap();
00137           if (val == 0.0)
00138             return lhs->simplify();
00139           
00140           return new rt_binary_expr<InterfaceType>(lhs->simplify(),
00141                                                    new op_binary<op_minus<NumericT>, InterfaceType>(),
00142                                                    new rt_constant<NumericT, InterfaceType>(val));
00143         }
00144         
00145         return new rt_binary_expr<InterfaceType>(lhs->simplify(),
00146                                                  new op_binary<op_minus<NumericT>, InterfaceType>(),
00147                                                  rhs->simplify());
00148   }
00149   
00151   template <typename InterfaceType, typename NumericT>
00152   bool can_simplify_impl(const InterfaceType * lhs, op_minus<NumericT>, const InterfaceType * rhs)
00153   {
00154       if (lhs->is_constant())
00155       {
00156         if (lhs->unwrap() == 0.0)
00157         {
00158           //std::cout << "can_simplify: true in op_minus" << std::endl;
00159           return true;
00160         }
00161       }
00162       
00163       if (rhs->is_constant())
00164       {
00165         if (rhs->unwrap() == 0.0)
00166         {
00167           //std::cout << "can_simplify: true in op_minus" << std::endl;
00168           return true;
00169         }
00170       }
00171       
00172       return lhs->can_simplify() || rhs->can_simplify();
00173   }
00174   
00175   
00176   
00177   
00178   //
00179   // multiplication
00180   //
00182   template <typename InterfaceType, typename NumericT>
00183   InterfaceType * diff_impl(const InterfaceType * lhs, op_mult<NumericT>, const InterfaceType * rhs, const InterfaceType * diff_var)
00184   {
00185       return new rt_binary_expr<InterfaceType>( new rt_binary_expr<InterfaceType>(lhs->diff(diff_var),
00186                                                                                   new op_binary<op_mult<NumericT>, InterfaceType>(),
00187                                                                                   rhs->clone()),
00188                                                 new op_binary<op_plus<NumericT>, InterfaceType>(),
00189                                                 new rt_binary_expr<InterfaceType>(lhs->clone(),
00190                                                                                   new op_binary<op_mult<NumericT>, InterfaceType>(),
00191                                                                                   rhs->diff(diff_var) )
00192                             );
00193   }
00194   
00196   template <typename InterfaceType, typename NumericT>
00197   InterfaceType * simplify_impl(const InterfaceType * lhs, op_mult<NumericT>, const InterfaceType * rhs)
00198   {
00199         if (lhs->is_constant())
00200         {
00201           NumericT val = lhs->unwrap();
00202           if (val == 0.0)
00203             return new rt_constant<NumericT, InterfaceType>(0.0);
00204           if (val == 1.0)
00205             return rhs->simplify();
00206           
00207           return new rt_binary_expr<InterfaceType>(new rt_constant<NumericT, InterfaceType>(val),
00208                                                    new op_binary<op_mult<NumericT>, InterfaceType>(),
00209                                                    rhs->simplify());
00210         }
00211         else if (rhs->is_constant())
00212         {
00213           NumericT val = rhs->unwrap();
00214           if (val == 0.0)
00215             return new rt_constant<NumericT, InterfaceType>(0.0);
00216           if (val == 1.0)
00217             return lhs->simplify();
00218           
00219           return new rt_binary_expr<InterfaceType>(lhs->simplify(),
00220                                                    new op_binary<op_mult<NumericT>, InterfaceType>(),
00221                                                    new rt_constant<NumericT, InterfaceType>(val));
00222         }
00223         
00224         rt_vector_expr<InterfaceType> const * lhs_vec = dynamic_cast<rt_vector_expr<InterfaceType> const *>(lhs);
00225         rt_vector_expr<InterfaceType> const * rhs_vec = dynamic_cast<rt_vector_expr<InterfaceType> const *>(rhs);
00226         
00227         if (lhs_vec != NULL && rhs_vec != NULL)
00228           return (*lhs_vec * *rhs_vec).get()->clone();
00229         
00230         return new rt_binary_expr<InterfaceType>(lhs->simplify(),
00231                                                  new op_binary<op_mult<NumericT>, InterfaceType>(),
00232                                                  rhs->simplify());
00233   }
00234   
00236   template <typename InterfaceType, typename NumericT>
00237   bool can_simplify_impl(const InterfaceType * lhs, op_mult<NumericT>, const InterfaceType * rhs)
00238   {
00239       if (lhs->is_constant())
00240       {
00241         NumericT val = lhs->unwrap();
00242         if (val == 0.0)
00243         {
00244           //std::cout << "can_simplify: true in op_mult" << std::endl;
00245           return true;
00246         }
00247         if (val == 1.0)
00248         {
00249           //std::cout << "can_simplify: true in op_mult" << std::endl;
00250           return true;
00251         }
00252       }
00253       if (rhs->is_constant())
00254       {
00255         NumericT val = rhs->unwrap();
00256         if (val == 0.0)
00257         {
00258           //std::cout << "can_simplify: true in op_mult" << std::endl;
00259           return true;
00260         }
00261         if (val == 1.0)
00262         {
00263           //std::cout << "can_simplify: true in op_mult" << std::endl;
00264           return true;
00265         }
00266       }
00267       
00268       rt_vector_expr<InterfaceType> const * lhs_vec = dynamic_cast<rt_vector_expr<InterfaceType> const *>(lhs);
00269       rt_vector_expr<InterfaceType> const * rhs_vec = dynamic_cast<rt_vector_expr<InterfaceType> const *>(rhs);
00270       
00271       if (lhs_vec != NULL && rhs_vec != NULL)
00272         return true;
00273       
00274       return lhs->can_simplify() || rhs->can_simplify();
00275   }
00276   
00277   
00278   
00279   
00280   //
00281   // division
00282   //
00284   template <typename InterfaceType, typename NumericT>
00285   InterfaceType * diff_impl(const InterfaceType * lhs, op_div<NumericT>, const InterfaceType * rhs, const InterfaceType * diff_var)
00286   {
00287     return new rt_binary_expr<InterfaceType>( new rt_binary_expr<InterfaceType>( new rt_binary_expr<InterfaceType>(lhs->diff(diff_var),
00288                                                                                                                    new op_binary<op_mult<NumericT>, InterfaceType>(),
00289                                                                                                                    rhs->clone()),
00290                                                                                  new op_binary<op_minus<NumericT>, InterfaceType>(),
00291                                                                                  new rt_binary_expr<InterfaceType>(lhs->clone(),
00292                                                                                                                    new op_binary<op_mult<NumericT>, InterfaceType>(),
00293                                                                                                                    rhs->diff(diff_var))
00294                                                                          ),
00295                                               new op_binary<op_div<NumericT>, InterfaceType>(),
00296                                               new rt_binary_expr<InterfaceType>(rhs->clone(),
00297                                                                                 new op_binary<op_mult<NumericT>, InterfaceType>(),
00298                                                                                 rhs->clone())
00299                                          );
00300   }
00301   
00303   template <typename InterfaceType, typename NumericT>
00304   InterfaceType * simplify_impl(const InterfaceType * lhs, op_div<NumericT>, const InterfaceType * rhs)
00305   {
00306     if (lhs->is_constant())
00307     {
00308       NumericT val = lhs->unwrap();
00309       if (val == 0.0)
00310         return new rt_constant<NumericT, InterfaceType>(0.0);
00311       
00312       return new rt_binary_expr<InterfaceType>(new rt_constant<NumericT, InterfaceType>(val),
00313                                                new op_binary<op_div<NumericT>, InterfaceType>(),
00314                                                rhs->simplify());
00315     }
00316     else if (rhs->is_constant())
00317     {
00318       NumericT val = rhs->unwrap();
00319       if (val == 1.0)
00320         return lhs->simplify();
00321       
00322       return new rt_binary_expr<InterfaceType>(lhs->simplify(),
00323                                                new op_binary<op_div<NumericT>, InterfaceType>(),
00324                                                new rt_constant<NumericT, InterfaceType>(val));
00325     }
00326     
00327     return new rt_binary_expr<InterfaceType>(lhs->simplify(),
00328                                              new op_binary<op_div<NumericT>, InterfaceType>(),
00329                                              rhs->simplify());
00330   }
00331   
00333   template <typename InterfaceType, typename NumericT>
00334   bool can_simplify_impl(const InterfaceType * lhs, op_div<NumericT>, const InterfaceType * rhs)
00335   {
00336     if (lhs->is_constant())
00337     {
00338       if (lhs->unwrap() == 0.0)
00339       {
00340         //std::cout << "can_simplify: true in op_div" << std::endl;
00341         return true;
00342       }
00343     }
00344     if (rhs->is_constant())
00345     {
00346       if (rhs->unwrap() == 1.0)
00347       {
00348         //std::cout << "can_simplify: true in op_div" << std::endl;
00349         return true;
00350       }
00351     }
00352     return lhs->can_simplify() || rhs->can_simplify();
00353   }
00354   
00355   
00356   
00357 }
00358 
00359 #endif

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