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

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

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_MANIPULATION_INTEGRATE_HPP
00002 #define VIENNAMATH_MANIPULATION_INTEGRATE_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/compiletime/ct_interval.hpp"
00022 #include "viennamath/manipulation/expand.hpp"
00023 #include "viennamath/manipulation/simplify.hpp"
00024 #include "viennamath/manipulation/substitute.hpp"
00025 
00030 namespace viennamath
00031 {
00032   //
00034   //
00035   
00036   namespace result_of
00037   {
00039     template <typename VariableType, typename ExpressionType>
00040     struct polynomial_degree
00041     {
00042       enum { value = 0 }; 
00043     };
00044     
00046     template <typename VariableType>
00047     struct polynomial_degree <VariableType, VariableType>
00048     {
00049       enum { value = 1 }; 
00050     };
00051 
00053     template <typename VariableType,
00054               typename LHS, typename NumericT, typename RHS>
00055     struct polynomial_degree <VariableType, ct_binary_expr<LHS, op_plus<NumericT>, RHS> >
00056     {
00057       typedef typename ct_binary_expr<LHS, op_plus<NumericT>, RHS>::ERROR_CANNOT_DEDUCE_POLYNOMIAL_DEGREE_FROM_SUM    error_type;
00058     };
00059 
00061     template <typename VariableType,
00062               typename LHS, typename NumericT, typename RHS>
00063     struct polynomial_degree <VariableType, ct_binary_expr<LHS, op_minus<NumericT>, RHS> >
00064     {
00065       typedef typename ct_binary_expr<LHS, op_plus<NumericT>, RHS>::ERROR_CANNOT_DEDUCE_POLYNOMIAL_DEGREE_FROM_SUM    error_type;
00066     };
00067     
00069     template <typename VariableType,
00070               typename LHS, typename NumericT, typename RHS>
00071     struct polynomial_degree <VariableType, ct_binary_expr<LHS, op_mult<NumericT>, RHS> >
00072     {
00073       enum { value = polynomial_degree<VariableType, LHS>::value + polynomial_degree<VariableType, RHS>::value }; 
00074     };
00075 
00077     template <typename VariableType,
00078               typename LHS, typename NumericT, typename RHS>
00079     struct polynomial_degree <VariableType, ct_binary_expr<LHS, op_div<NumericT>, RHS> >
00080     {
00081       enum { value = polynomial_degree<VariableType, LHS>::value - polynomial_degree<VariableType, RHS>::value }; 
00082     };
00083     
00084     
00085     // compute power of an expression
00087     template <typename T, long exponent>
00088     struct pow 
00089     {
00090       // balance generated binary expression equally between LHS and RHS:
00091       typedef ct_binary_expr< typename pow<T, exponent / 2>::type,
00092                               op_mult<default_numeric_type>,
00093                               typename pow<T, exponent - exponent / 2>::type>  type;
00094     };
00095     
00097     template <typename T>
00098     struct pow <T, 0>
00099     {
00100       typedef ct_constant<1>  type;
00101     };
00102 
00104     template <typename T>
00105     struct pow <T, 1>
00106     {
00107       typedef T  type;
00108     };
00109 
00111     template <typename T>
00112     struct pow <T, 2>
00113     {
00114       typedef ct_binary_expr<T, op_mult<default_numeric_type>, T>  type;
00115     };
00116 
00117     
00118     
00119     //integrate monomial:
00121     template <typename VariableType,
00122               long exponent>
00123     struct integrate_monomial
00124     {
00125       typedef ct_binary_expr< typename pow<VariableType, exponent + 1>::type,
00126                               op_div<default_numeric_type>,
00127                               ct_constant<exponent + 1>
00128                             >         type;
00129     };
00130 
00132     template <typename VariableType>
00133     struct integrate_monomial < VariableType, 0>
00134     {
00135       typedef VariableType      type;
00136     };
00137     
00138     
00140     
00150     template <typename LowerBound, typename UpperBound,
00151               typename IntegrandType,
00152               typename VariableType>
00153     struct integrate {}; //SFINAE for interface function viennamath::integrate()
00154     
00155     
00156     namespace detail
00157     {
00159       template <typename LowerBound, typename UpperBound,
00160                 typename IntegrandType,
00161                 typename VariableType>
00162       struct integrate_impl {};
00163       
00164       
00165       
00166       template <typename LowerBound, typename UpperBound,
00167                 typename LHS, typename NumericT, typename RHS,
00168                 typename VariableType>
00169       struct integrate_impl <LowerBound, UpperBound,
00170                             ct_binary_expr<LHS, op_plus<NumericT>, RHS>,
00171                             VariableType
00172                             >
00173       {
00174         typedef ct_binary_expr< typename integrate_impl<LowerBound, UpperBound, LHS, VariableType>::type,
00175                                 op_plus<NumericT>,
00176                                 typename integrate_impl<LowerBound, UpperBound, RHS, VariableType>::type
00177                               >                   integrated_type;
00178                               
00179         typedef typename viennamath::result_of::simplify<integrated_type>::type    type;
00180       };
00181 
00182       template <typename LowerBound, typename UpperBound,
00183                 typename LHS, typename NumericT, typename RHS,
00184                 typename VariableType>
00185       struct integrate_impl <LowerBound, UpperBound,
00186                             ct_binary_expr<LHS, op_minus<NumericT>, RHS>,
00187                             VariableType
00188                             >
00189       {
00190         typedef ct_binary_expr< typename integrate_impl<LowerBound, UpperBound, LHS, VariableType>::type,
00191                                 op_minus<NumericT>,
00192                                 typename integrate_impl<LowerBound, UpperBound, RHS, VariableType>::type
00193                               >                   integrated_type;
00194                               
00195         typedef typename viennamath::result_of::simplify<integrated_type>::type    type;
00196       };
00197 
00198 
00199       template <typename LowerBound, typename UpperBound,
00200                 typename LHS, typename NumericT, typename RHS,
00201                 typename VariableType>
00202       struct integrate_impl <LowerBound, UpperBound,
00203                             ct_binary_expr<LHS, op_mult<NumericT>, RHS>,
00204                             VariableType
00205                             >
00206       {
00207         //extract coefficient:
00208         typedef typename viennamath::result_of::substitute< VariableType,
00209                                                             ct_constant<1>,
00210                                                             ct_binary_expr<LHS, op_mult<NumericT>, RHS> >::type    coefficient_type;
00211                                                             
00212         typedef typename viennamath::result_of::simplify<coefficient_type>::type    simplified_coefficient_type;                                                    
00213         
00214         enum { exponent = polynomial_degree<VariableType, 
00215                                             ct_binary_expr<LHS, op_mult<NumericT>, RHS>
00216                                           >::value  };
00217         
00218         typedef ct_binary_expr< typename integrate_monomial<UpperBound, exponent>::type,
00219                                 op_mult<NumericT>,
00220                                 simplified_coefficient_type
00221                               >                    upper_contribution;    
00222 
00223         typedef ct_binary_expr< typename integrate_monomial<LowerBound, exponent>::type,
00224                                 op_mult<NumericT>,
00225                                 simplified_coefficient_type
00226                               >                    lower_contribution;    
00227                               
00228         typedef ct_binary_expr< typename simplify<upper_contribution>::type,
00229                                 op_minus<NumericT>,
00230                                 typename simplify<lower_contribution>::type
00231                               >            integrated_type;                      
00232         
00233         typedef typename viennamath::result_of::simplify<integrated_type>::type    type;
00234       };
00235 
00236       template <typename LowerBound, typename UpperBound,
00237                 typename LHS, typename NumericT, typename RHS,
00238                 typename VariableType>
00239       struct integrate_impl <LowerBound, UpperBound,
00240                             ct_binary_expr<LHS, op_div<NumericT>, RHS>,
00241                             VariableType
00242                             >
00243       {
00244         //assume polynomial, thus integrate numerator only:
00245         typedef ct_binary_expr< typename integrate_impl<LowerBound, UpperBound,
00246                                                         LHS,
00247                                                         VariableType>::type,
00248                                 op_div<NumericT>,
00249                                 RHS>                     integrated_type;
00250                                 
00251         typedef typename viennamath::result_of::simplify<integrated_type>::type    type;
00252       };
00253       
00254       template <typename LowerBound, typename UpperBound,
00255                 typename LHS, typename OP,
00256                 typename VariableType>
00257       struct integrate_impl <LowerBound, UpperBound,
00258                             ct_unary_expr<LHS, OP>,
00259                             VariableType
00260                             >
00261       {
00262         typedef typename ct_unary_expr<LHS, OP>::ERROR_INTEGRATION_OF_UNARY_EXPRESSION_NOT_SUPPORTED    type;
00263       };
00264 
00265       template <typename LowerBound, typename UpperBound,
00266                 long value,
00267                 typename VariableType>
00268       struct integrate_impl <LowerBound, UpperBound,
00269                             ct_constant<value>,
00270                             VariableType
00271                             >
00272       {
00273         typedef ct_binary_expr<UpperBound,
00274                               op_minus<default_numeric_type>,
00275                               LowerBound
00276                               >                    interval_length;
00277                               
00278         typedef ct_binary_expr< ct_constant<value>,
00279                                 op_mult<default_numeric_type>,
00280                                 interval_length
00281                               >    integrated_type;
00282                               
00283         typedef typename viennamath::result_of::simplify<integrated_type>::type   type;
00284       };
00285 
00286       template <typename LowerBound, typename UpperBound,
00287                 typename TAG,
00288                 typename VariableType>
00289       struct integrate_impl <LowerBound, UpperBound,
00290                             ct_function_symbol<TAG>,
00291                             VariableType
00292                             >
00293       {
00294         typedef typename ct_function_symbol<TAG>::ERROR_INTEGRATION_OF_FUNCTION_SYMBOL_NOT_SUPPORTED    type;
00295       };
00296       
00297       template <typename LowerBound, typename UpperBound,
00298                 id_type id,
00299                 typename VariableType>
00300       struct integrate_impl <LowerBound, UpperBound,
00301                             ct_variable<id>,
00302                             VariableType
00303                             >
00304       {
00305         typedef ct_binary_expr< ct_binary_expr<UpperBound,
00306                                               op_mult<default_numeric_type>,
00307                                               UpperBound
00308                                               >,
00309                                 op_div<default_numeric_type>,
00310                                 ct_constant<2>
00311                               >    upper_contribution;
00312 
00313         typedef ct_binary_expr< ct_binary_expr<LowerBound,
00314                                               op_mult<default_numeric_type>,
00315                                               LowerBound
00316                                               >,
00317                                 op_div<default_numeric_type>,
00318                                 ct_constant<2>
00319                               >    lower_contribution;
00320                               
00321         typedef ct_binary_expr<upper_contribution,
00322                               op_minus<default_numeric_type>,
00323                               lower_contribution>      integrated_type;                      
00324                               
00325         typedef typename viennamath::result_of::simplify<integrated_type>::type   type;
00326       };
00327       
00328     } //namespace detail
00329     
00330     //
00331     // public metafunction overloads:
00332     
00334     template <typename LowerBound, typename UpperBound,
00335               typename LHS, typename OP, typename RHS,
00336               typename VariableType>
00337     struct integrate <LowerBound, UpperBound,
00338                       ct_binary_expr<LHS, OP, RHS>,
00339                       VariableType
00340                      >
00341     {
00342       //prepare 
00343       typedef ct_binary_expr<LHS, OP, RHS>                                        IntegrandType;
00344       typedef typename viennamath::result_of::expand<IntegrandType>::type         expanded_integrand;
00345       typedef typename viennamath::result_of::simplify<expanded_integrand>::type  simplified_integrand;
00346       
00347       typedef typename detail::integrate_impl<LowerBound, UpperBound,
00348                                               simplified_integrand,
00349                                               VariableType>::type    type;
00350       
00351     };
00352 
00354     template <typename LowerBound, typename UpperBound,
00355               typename LHS, typename OP,
00356               typename VariableType>
00357     struct integrate <LowerBound, UpperBound,
00358                       ct_unary_expr<LHS, OP>,
00359                       VariableType
00360                      >
00361     {
00362       typedef typename ct_unary_expr<LHS, OP>::ERROR_INTEGRATION_OF_UNARY_EXPRESSION_NOT_SUPPORTED    type;
00363     };
00364 
00366     template <typename LowerBound, typename UpperBound,
00367               long value,
00368               typename VariableType>
00369     struct integrate <LowerBound, UpperBound,
00370                       ct_constant<value>,
00371                       VariableType
00372                      >
00373     {
00374       typedef typename detail::integrate_impl<LowerBound, UpperBound, ct_constant<value>, VariableType >::type    type;
00375     };
00376 
00378     template <typename LowerBound, typename UpperBound,
00379               typename TAG,
00380               typename VariableType>
00381     struct integrate <LowerBound, UpperBound,
00382                       ct_function_symbol<TAG>,
00383                       VariableType
00384                      >
00385     {
00386       typedef typename ct_function_symbol<TAG>::ERROR_INTEGRATION_OF_FUNCTION_SYMBOL_NOT_SUPPORTED    type;
00387     };
00388     
00390     template <typename LowerBound, typename UpperBound,
00391               id_type id,
00392               typename VariableType>
00393     struct integrate <LowerBound, UpperBound,
00394                       ct_variable<id>,
00395                       VariableType
00396                      >
00397     {
00398       typedef typename detail::integrate_impl<LowerBound, UpperBound, ct_variable<id>, VariableType >::type    type;
00399     };
00400     
00401     
00402   } // namespace result_of
00403 
00410   template <typename LowerBound, typename UpperBound,
00411             typename IntegrandType,
00412             typename VariableType>
00413   typename result_of::integrate<LowerBound, UpperBound,
00414                                 IntegrandType,
00415                                 VariableType>::type
00416   integrate( ct_interval<LowerBound, UpperBound> const & interv,
00417              IntegrandType const & integrand,
00418              VariableType const & var)
00419   {
00420     return typename result_of::integrate<LowerBound, UpperBound,
00421                                          IntegrandType,
00422                                          VariableType>::type();
00423   }
00424 
00425   
00427   
00428   //TODO: Symbolic integration at run time not provided yet
00429   
00430 }
00431 
00432 #endif

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