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

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

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_MANIPULATION_COEFFICIENT_HPP
00002 #define VIENNAMATH_MANIPULATION_COEFFICIENT_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/manipulation/expand.hpp"
00022 
00027 namespace viennamath
00028 {
00030   namespace result_of
00031   {
00033     namespace detail
00034     {
00035       // forward declaration
00036       template <typename FactorType,
00037                 typename ExpressionType>
00038       struct coefficient_impl;
00039 
00040       
00041       
00042       //
00043       // Helper metafunction: Returns the number of factors FactorType found in ExpressionType
00044       template <typename FactorType,
00045                 typename ExpressionType>
00046       struct has_factor
00047       {
00048         enum { value = 0 };
00049       };
00050       
00051       template <typename FactorType>
00052       struct has_factor<FactorType, FactorType>
00053       {
00054         enum { value = 1 };
00055       };
00056 
00057       template <typename FactorType,
00058                 typename LHS, typename NumericT, typename RHS>
00059       struct has_factor< FactorType, ct_binary_expr<LHS, op_plus<NumericT>, RHS> >
00060       {
00061         typedef typename ct_binary_expr<LHS, op_plus<NumericT>, RHS>::ERROR_EXPRESSION_NOT_FULLY_EXPANDED    error_type;
00062         enum { value = 0 };
00063       };
00064       
00065       template <typename FactorType,
00066                 typename LHS, typename NumericT, typename RHS>
00067       struct has_factor< FactorType, ct_binary_expr<LHS, op_minus<NumericT>, RHS> >
00068       {
00069         typedef typename ct_binary_expr<LHS, op_minus<NumericT>, RHS>::ERROR_EXPRESSION_NOT_FULLY_EXPANDED    error_type;
00070         enum { value = 0 };
00071       };
00072       
00073       template <typename FactorType,
00074                 typename LHS, typename NumericT, typename RHS>
00075       struct has_factor< FactorType, ct_binary_expr<LHS, op_mult<NumericT>, RHS> >
00076       {
00077         enum { value = has_factor<FactorType, LHS>::value + has_factor<FactorType, RHS>::value };
00078       };
00079       
00080       template <typename FactorType,
00081                 typename LHS, typename NumericT, typename RHS>
00082       struct has_factor< FactorType, ct_binary_expr<LHS, op_div<NumericT>, RHS> >
00083       {
00084         enum { value = has_factor<FactorType, LHS>::value };
00085       };
00086       
00087       
00088       //
00089       // Extracts the factor from an expression free of plus and minus operations
00090       template <typename FactorType,
00091                 typename LHS, typename NumericT, typename RHS,
00092                 bool lhs_has_factor = (has_factor<FactorType, LHS>::value != 0),
00093                 bool rhs_has_factor = (has_factor<FactorType, RHS>::value != 0)
00094                 >
00095       struct extract_factor_from_product
00096       {
00097         // default case: neither LHS nor RHS have the factor
00098         typedef ct_constant<0>     type;
00099       };
00100       
00101       template <typename FactorType,
00102                 typename LHS, typename NumericT, typename RHS>
00103       struct extract_factor_from_product<FactorType, LHS, NumericT, RHS, true, false>
00104       {
00105         // get the factor from LHS:
00106         typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00107                                 op_mult<NumericT>,
00108                                 RHS
00109                               >                    type;
00110       };
00111 
00112       template <typename FactorType,
00113                 typename LHS, typename NumericT, typename RHS>
00114       struct extract_factor_from_product<FactorType, LHS, NumericT, RHS, false, true>
00115       {
00116         // get the factor from RHS:
00117         typedef ct_binary_expr< LHS,
00118                                 op_mult<NumericT>,
00119                                 typename coefficient_impl<FactorType, RHS>::type
00120                               >                    type;
00121       };
00122 
00123       template <typename FactorType,
00124                 typename LHS, typename NumericT, typename RHS>
00125       struct extract_factor_from_product<FactorType, LHS, NumericT, RHS, true, true>
00126       {
00127         // if both LHS and RHS contain the factor, we extract the coefficient from the LHS and multiply with RHS
00128         typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00129                                 op_mult<NumericT>,
00130                                 RHS
00131                               >                    type;
00132       };
00133       
00134 
00135       //
00136       // Tokenizer: Extracts the factor from each token
00137       template <typename FactorType,
00138                 typename ExpressionType>
00139       struct coefficient_impl
00140       {
00141         typedef ct_constant<0>   type;
00142       };
00143 
00144       template <typename FactorType>
00145       struct coefficient_impl<FactorType, FactorType>
00146       {
00147         typedef ct_constant<1>    type;
00148       };
00149       
00150       template <typename FactorType,
00151                 typename LHS, typename NumericT, typename RHS>
00152       struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_plus<NumericT>, RHS> >
00153       {
00154         typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00155                                 op_plus<NumericT>,
00156                                 typename coefficient_impl<FactorType, RHS>::type
00157                               >   type;
00158       };
00159 
00160       template <typename FactorType,
00161                 typename LHS, typename NumericT, typename RHS>
00162       struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_minus<NumericT>, RHS> >
00163       {
00164         typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00165                                 op_minus<NumericT>,
00166                                 typename coefficient_impl<FactorType, RHS>::type
00167                               >   type;
00168       };
00169 
00170       template <typename FactorType,
00171                 typename LHS, typename NumericT, typename RHS>
00172       struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_mult<NumericT>, RHS> >
00173       {
00174         typedef typename extract_factor_from_product<FactorType, LHS, NumericT, RHS>::type    type;
00175       };
00176 
00177       template <typename FactorType,
00178                 typename NumericT, typename RHS>
00179       struct coefficient_impl< FactorType, ct_binary_expr<FactorType, op_mult<NumericT>, RHS> >
00180       {
00181         typedef RHS    type;
00182       };
00183 
00184       template <typename FactorType,
00185                 typename LHS, typename NumericT>
00186       struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_mult<NumericT>, FactorType> >
00187       {
00188         typedef LHS    type;
00189       };
00190 
00191       template <typename FactorType,
00192                 typename NumericT>
00193       struct coefficient_impl< FactorType, ct_binary_expr<FactorType, op_mult<NumericT>, FactorType> >
00194       {
00195         typedef FactorType    type;
00196       };
00197       
00198       template <typename FactorType,
00199                 typename LHS, typename NumericT, typename RHS>
00200       struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_div<NumericT>, RHS> >
00201       {
00202         typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00203                                 op_div<NumericT>,
00204                                 RHS
00205                               >   type;
00206       };
00207       
00208     } //namespace detail
00209     
00210     //
00211     // Interface metafunction:
00217     template <typename FactorType,
00218               typename ExpressionType>
00219     struct coefficient
00220     {
00221       typedef typename viennamath::result_of::expand<ExpressionType>::type    expanded_expression;
00222       
00223       typedef typename detail::coefficient_impl<FactorType, expanded_expression>::type    type;
00224     };
00225   }
00226   
00227   
00228   //public interface:
00234   template <typename FactorType,
00235             typename ExpressionType>
00236   typename viennamath::result_of::coefficient<FactorType, ExpressionType>::type
00237   coefficient(FactorType const & f, ExpressionType const & e)
00238   {
00239     return typename viennamath::result_of::coefficient<FactorType, ExpressionType>::type();
00240   }
00241   
00242   
00243   
00244   
00245   
00247   
00248   // Not yet available
00249   
00250 }
00251 
00252 #endif

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