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

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

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_MANIPULATION_EXPAND_HPP
00002 #define VIENNAMATH_MANIPULATION_EXPAND_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/compiletime/unary_op_tags.hpp"
00023 #include "viennamath/runtime/interval.hpp"
00024 #include "viennamath/runtime/symbolic_interval.hpp"
00025 #include "viennamath/runtime/integral.hpp"
00026 
00031 namespace viennamath
00032 {
00034   
00035   namespace result_of
00036   {
00043     template <typename T>
00044     struct expand {}; //Uses SFINAE for proper overloading of viennamath::expand()
00045     
00046     
00047     namespace detail
00048     {
00049       // checks for the occurance of plus or minus in an expression
00050       template <typename T>
00051       struct has_plus_or_minus 
00052       {
00053         enum { value = 0 };
00054       };
00055       
00056       template <typename LHS, typename NumericT, typename RHS>
00057       struct has_plus_or_minus< ct_binary_expr<LHS, op_plus<NumericT>, RHS> >
00058       {
00059         enum { value = 1 };
00060       };
00061 
00062       template <typename LHS, typename NumericT, typename RHS>
00063       struct has_plus_or_minus< ct_binary_expr<LHS, op_minus<NumericT>, RHS> >
00064       {
00065         enum { value = 1 };
00066       };
00067 
00068       template <typename LHS, typename NumericT, typename RHS>
00069       struct has_plus_or_minus< ct_binary_expr<LHS, op_mult<NumericT>, RHS> >
00070       {
00071         enum { value = has_plus_or_minus<LHS>::value + has_plus_or_minus<RHS>::value };
00072       };
00073 
00074       template <typename LHS, typename NumericT, typename RHS>
00075       struct has_plus_or_minus< ct_binary_expr<LHS, op_div<NumericT>, RHS> >
00076       {
00077         enum { value = has_plus_or_minus<LHS>::value};
00078       };
00079       
00080       
00081       //
00082       template <typename ExpressionType,
00083                 typename FactorType,
00084                 bool needs_expansion = (has_plus_or_minus<ExpressionType>::value != 0) >
00085       struct expand_with_factor
00086       {
00087         typedef ct_binary_expr< ExpressionType,
00088                                 op_mult<default_numeric_type>,
00089                                 FactorType
00090                                 >                 type;
00091       };
00092       
00093       template <typename LHS, typename NumericT, typename RHS,
00094                 typename FactorType>
00095       struct expand_with_factor < ct_binary_expr<LHS, op_plus<NumericT>, RHS>,
00096                                   FactorType,
00097                                   true>
00098       {
00099         typedef ct_binary_expr< typename expand_with_factor<LHS, FactorType>::type,
00100                                 op_plus<NumericT>,
00101                                 typename expand_with_factor<RHS, FactorType>::type
00102                               >                   type;
00103       };
00104       
00105       
00106       template <typename LHS, typename NumericT, typename RHS,
00107                 typename FactorType>
00108       struct expand_with_factor < ct_binary_expr<LHS, op_minus<NumericT>, RHS>,
00109                                   FactorType,
00110                                   true>
00111       {
00112         typedef ct_binary_expr< typename expand_with_factor<LHS, FactorType>::type,
00113                                 op_minus<NumericT>,
00114                                 typename expand_with_factor<RHS, FactorType>::type
00115                               >                   type;
00116       };
00117 
00118       template <typename LHS, typename NumericT, typename RHS,
00119                 typename FactorType>
00120       struct expand_with_factor < ct_binary_expr<LHS, op_mult<NumericT>, RHS>,
00121                                   FactorType,
00122                                   true>
00123       {
00124         typedef typename viennamath::result_of::expand< ct_binary_expr<LHS, op_mult<NumericT>, RHS> >::type     expanded_type;
00125         typedef typename expand_with_factor< expanded_type, FactorType >::type         type;
00126       };
00127       
00128       template <typename LHS, typename NumericT, typename RHS,
00129                 typename FactorType>
00130       struct expand_with_factor < ct_binary_expr<LHS, op_div<NumericT>, RHS>,
00131                                   FactorType,
00132                                   true>
00133       {
00134         typedef ct_binary_expr< typename expand_with_factor<LHS, FactorType>::type,
00135                                 op_div<NumericT>,
00136                                 RHS
00137                               >                   type;
00138       };
00139 
00141       
00142       template <typename LHS,
00143                 typename RHS,
00144                 bool lhs_expandable = (has_plus_or_minus<LHS>::value != 0),
00145                 bool rhs_expandable = (has_plus_or_minus<RHS>::value != 0)>
00146       struct expand_product
00147       {
00148          //default case: both factors not expandable:
00149          typedef ct_binary_expr<LHS,
00150                                 op_mult<default_numeric_type>,
00151                                 RHS >     type;
00152       };
00153       
00154       template <typename LHS,
00155                 typename RHS>
00156       struct expand_product <LHS, RHS, true, false>
00157       {
00158          typedef typename expand_with_factor<LHS, RHS>::type   type;
00159       };
00160 
00161       template <typename LHS,
00162                 typename RHS>
00163       struct expand_product <LHS, RHS, false, true>
00164       {
00165          typedef typename expand_with_factor<RHS, LHS>::type   type;
00166       };
00167 
00168       template <typename LHS,
00169                 typename RHS>
00170       struct expand_product <LHS, RHS, true, true>
00171       {
00172          //First expand with factor RHS:
00173          typedef typename expand_with_factor<LHS, RHS>::type   intermediate_type;
00174          //then restart:
00175          typedef typename viennamath::result_of::expand<intermediate_type>::type      type;
00176       };
00177       
00178     } //namespace detail
00179     
00180     
00182     template <typename LHS, typename NumericT, typename RHS>
00183     struct expand< ct_binary_expr<LHS, op_plus<NumericT>, RHS> >
00184     {
00185       typedef ct_binary_expr<typename expand<LHS>::type,
00186                              op_plus<NumericT>,
00187                              typename expand<RHS>::type >     type;
00188     };
00189 
00191     template <typename LHS, typename NumericT, typename RHS>
00192     struct expand< ct_binary_expr<LHS, op_minus<NumericT>, RHS> >
00193     {
00194       typedef ct_binary_expr<typename expand<LHS>::type,
00195                              op_minus<NumericT>,
00196                              typename expand<RHS>::type >     type;
00197     };
00198 
00200     template <typename LHS, typename NumericT, typename RHS>
00201     struct expand< ct_binary_expr<LHS, op_mult<NumericT>, RHS> >
00202     {
00203       typedef typename detail::expand_product<LHS, RHS>::type    type;
00204     };
00205 
00207     template <typename LHS, typename NumericT, typename RHS>
00208     struct expand< ct_binary_expr<LHS, op_div<NumericT>, RHS> >
00209     {
00210       typedef ct_binary_expr<typename expand<LHS>::type,
00211                              op_div<NumericT>,
00212                              typename expand<RHS>::type >     type;
00213     };
00214 
00216     template <typename LHS, typename OP>
00217     struct expand< ct_unary_expr<LHS, OP> >
00218     {
00219       typedef ct_unary_expr<LHS, OP>      type;
00220     };
00221     
00223     template <typename TAG>
00224     struct expand< ct_function_symbol<TAG> >
00225     {
00226       typedef ct_function_symbol<TAG>      type;
00227     };
00228 
00230     template <long value>
00231     struct expand< ct_constant<value> >
00232     {
00233       typedef ct_constant<value>      type;
00234     };
00235 
00237     template <id_type id>
00238     struct expand< ct_variable<id> >
00239     {
00240       typedef ct_variable<id>      type;
00241     };
00242     
00243     
00244   }
00245   
00246   
00251   template <typename ExpressionType>
00252   typename result_of::expand<ExpressionType>::type
00253   expand(ExpressionType const & type)
00254   {
00255     return typename result_of::expand<ExpressionType>::type();
00256   }
00257   
00258   
00260   
00261   //TODO  Support to be added in one of the next releases of ViennaMath.
00262 }
00263 
00264 #endif

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