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

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

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_MANIPULATION_DIFF_HPP
00002 #define VIENNAMATH_MANIPULATION_DIFF_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 "viennamath/forwards.h"
00021 #include "viennamath/runtime/unary_expr.hpp"
00022 #include "viennamath/manipulation/simplify.hpp"
00023 
00028 namespace viennamath
00029 {
00030   //
00032   //
00033 
00039   template <typename InterfaceType>
00040   rt_expr<InterfaceType> diff(rt_binary_expr<InterfaceType> const & e,
00041                               rt_variable<InterfaceType> const & var)
00042   {
00043     rt_expr<InterfaceType> temp(e.diff(&var));
00044     inplace_simplify(temp);
00045     return temp;
00046   }
00047   
00053   template <typename InterfaceType>
00054   rt_expr<InterfaceType> diff(rt_unary_expr<InterfaceType> const & e,
00055                               rt_variable<InterfaceType> const & var)
00056   {
00057     rt_expr<InterfaceType> temp(e.diff(&var));
00058     inplace_simplify(temp);
00059     return temp;
00060   }
00061 
00067   template <typename InterfaceType>
00068   rt_expr<InterfaceType> diff(rt_expr<InterfaceType> const & e,
00069                               rt_variable<InterfaceType> const & var)
00070   {
00071     rt_expr<InterfaceType> temp(e.get()->diff(&var));
00072     inplace_simplify(temp);
00073     return temp;
00074   }
00075 
00076   //compile time variable:
00082   template <typename InterfaceType, id_type id>
00083   rt_expr<InterfaceType> diff(rt_binary_expr<InterfaceType> const & e,
00084                               ct_variable<id> const & var)
00085   {
00086     rt_variable<InterfaceType> temp(id);
00087     return diff(e, temp);
00088   }
00089 
00095   template <typename InterfaceType, id_type id>
00096   rt_expr<InterfaceType> diff(rt_unary_expr<InterfaceType> const & e,
00097                              ct_variable<id> const & var)
00098   {
00099     rt_variable<InterfaceType> temp(id);
00100     return diff(e, temp);
00101   }
00102 
00108   template <typename InterfaceType, id_type id>
00109   rt_expr<InterfaceType> diff(rt_expr<InterfaceType> const & e,
00110                               ct_variable<id> const & var)
00111   {
00112     rt_variable<InterfaceType> temp(id);
00113     return diff(e, temp);
00114   }
00115 
00116   
00117   //
00118   // Symbolic differentiation:
00119   //
00121   template <typename InterfaceType>
00122   rt_expr<InterfaceType> diff(rt_function_symbol<InterfaceType> const & other,
00123                               rt_variable<InterfaceType> const & var)
00124   {
00125     typedef op_partial_deriv<typename InterfaceType::numeric_type> d_dx_type;
00126     return rt_expr<InterfaceType>(new rt_unary_expr<InterfaceType>(other.clone(), 
00127                                                                    new op_unary<d_dx_type, InterfaceType>(d_dx_type(var.id()))
00128                                                                   )
00129                                  );
00130   }
00131   
00133   template <typename InterfaceType, id_type id>
00134   rt_expr<InterfaceType> diff(rt_function_symbol<InterfaceType> const & other,
00135                               ct_variable<id> const & var)
00136   {
00137     typedef op_partial_deriv<typename InterfaceType::numeric_type> d_dx_type;
00138     return rt_expr<InterfaceType>(new rt_unary_expr<InterfaceType>(other.clone(), 
00139                                                                    new op_unary<d_dx_type, InterfaceType>(d_dx_type(id))
00140                                                                   )
00141                                  );
00142   }
00143 
00145 
00147   template <typename InterfaceType>
00148   rt_constant<typename InterfaceType::numeric_type> diff(typename InterfaceType::numeric_type value,
00149                                                          rt_variable<InterfaceType> const & var)
00150   {
00151     return rt_constant<typename InterfaceType::numeric_type>(0);
00152   }
00153   
00155   template <typename OtherScalarType, typename InterfaceType>
00156   rt_constant<typename InterfaceType::numeric_type> diff(rt_constant<OtherScalarType, InterfaceType> const & c,
00157                                                          rt_variable<InterfaceType> const & var)
00158   {
00159     return rt_constant<typename InterfaceType::numeric_type>(0);
00160   }
00161 
00163 
00165   template <id_type other_id, typename InterfaceType,
00166             id_type id>
00167   rt_constant<typename InterfaceType::numeric_type> diff(rt_variable<InterfaceType> const & c,
00168                                                          rt_variable<InterfaceType> const & var)
00169   {
00170     if (c.id() == var.id())
00171       return rt_constant<typename InterfaceType::numeric_type>(1);
00172       
00173     return rt_constant<typename InterfaceType::numeric_type>(0);
00174   }
00175 
00176 
00177   //
00179   //
00180   
00181 
00182   //metafunctions
00183   namespace result_of
00184   {
00185     //differentiates ARG with respect to VAR
00191     template <typename ARG, typename VAR>
00192     struct diff {}; //default case: used for SFINAE with respect to the viennamath::diff() function
00193     //{
00194     //  typedef typename ARG::ERROR_INVALID_ARGUMENT_PROVIDED_TO_COMPILE_TIME_DIFFERENTIATION  error_type; 
00195     //};
00196     
00197 
00199     template <typename LHS, typename RHS, id_type id>
00200     struct diff<ct_binary_expr<LHS, op_plus<default_numeric_type>, RHS>,
00201                 ct_variable<id> >
00202     {
00203       typedef ct_binary_expr< typename diff<LHS, ct_variable<id> >::result_type,
00204                               op_plus<default_numeric_type>,
00205                               typename diff<RHS, ct_variable<id> >::result_type >     result_type;    
00206     };
00207     
00209     template <typename LHS, typename RHS, id_type id>
00210     struct diff<ct_binary_expr<LHS, op_minus<default_numeric_type>, RHS>,
00211                 ct_variable<id> >
00212     {
00213       typedef ct_binary_expr< typename diff<LHS, ct_variable<id> >::result_type,
00214                               op_minus<default_numeric_type>,
00215                               typename diff<RHS, ct_variable<id> >::result_type >     result_type;    
00216     };
00217     
00219     template <typename LHS, typename RHS, id_type id>
00220     struct diff<ct_binary_expr<LHS, op_mult<default_numeric_type>, RHS>,
00221                 ct_variable<id> >
00222     {
00223       typedef ct_binary_expr< ct_binary_expr< typename diff<LHS, ct_variable<id> >::result_type,
00224                                               op_mult<default_numeric_type>,
00225                                               RHS>,
00226                               op_plus<default_numeric_type>,            
00227                               ct_binary_expr< LHS,
00228                                               op_mult<default_numeric_type>,
00229                                               typename diff<RHS, ct_variable<id> >::result_type >
00230                             >                                                      result_type;    
00231     };
00232 
00234     template <typename LHS, typename RHS, id_type id>
00235     struct diff<ct_binary_expr<LHS, op_div<default_numeric_type>, RHS>,
00236                 ct_variable<id> >
00237     {
00238       typedef ct_binary_expr< ct_binary_expr< ct_binary_expr< typename diff<LHS, ct_variable<id> >::result_type,
00239                                                               op_mult<default_numeric_type>,
00240                                                               RHS>,
00241                                               op_minus<default_numeric_type>,            
00242                                               ct_binary_expr< LHS,
00243                                                               op_mult<default_numeric_type>,
00244                                                               typename diff<RHS, ct_variable<id> >::result_type >
00245                                             >,
00246                               op_div<default_numeric_type>,             
00247                               ct_binary_expr< RHS,
00248                                               op_mult<default_numeric_type>,
00249                                               RHS >
00250                             >                 result_type;    
00251     };
00252     
00254     template <id_type other_id,
00255               id_type id>
00256     struct diff< ct_variable<other_id>,
00257                  ct_variable<id> >
00258     {
00259       typedef ct_constant<0>    result_type;    
00260     };
00261     
00263     template <id_type id>
00264     struct diff< ct_variable<id>,
00265                  ct_variable<id> >
00266     {
00267       typedef ct_constant<1>    result_type;    
00268     };
00269     
00271     template <long value, id_type id>
00272     struct diff< ct_constant<value>,
00273                  ct_variable<id> >
00274     {
00275       typedef ct_constant<0>    result_type;    
00276     };
00277     
00278   } // namespace result_of
00279   
00280   
00281   //
00282   // interface functions
00283   //
00285   template <typename ExpressionType,
00286             id_type id>
00287   typename result_of::diff<ExpressionType,
00288                            ct_variable<id> >::result_type
00289   diff(ExpressionType const & c,
00290        ct_variable<id> const & var)
00291   {
00292     return typename result_of::diff<ExpressionType,
00293                                     ct_variable<id> >::result_type();
00294   }
00295   
00296   
00297   
00298 }
00299 
00300 #endif

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